nalexn / ViewInspector

Runtime introspection and unit testing of SwiftUI views
MIT License
2.09k stars 145 forks source link

Question: trying to use the (super) ViewInspector in non test code #271

Closed simonb-applanga closed 8 months ago

simonb-applanga commented 8 months ago

Hey,

First thank you for the hard work to create this framework!

I wanted to try and use it in my internal dev tool (would not be released) where I need to inspect the SwiftUI view hierarchy. I've cloned the code and made some changes to remove the XCTest usage so I can run it, and I see it run and finds the SwiftUI elements like Text, Button.

The issue I encountered and I know is a limitation is due to the app using @StateObject, and @EnvironmentObject. I understand why it doesn't work during an xcode test, but I'm running it on a currently presented view, shouldn't the data tree be available for ViewInspector?

I saw that originally the body is re-created and the view struct is cloned, so I tried to remove that code

internal extension Content {
    var isCustomView: Bool {
        return !Inspector.isSystemType(value: view)
    }

    func extractCustomView() throws -> Content {
//        let contentExtractor = try ContentExtractor(source: view)
//        let view = try contentExtractor.extractContent(environmentObjects: medium.environmentObjects)
//        let medium = self.medium.resettingViewModifiers()
        return try Inspector.unwrap(view: view, medium: medium)
    }

    func extractCustomViewGroup() throws -> LazyGroup<Content> {
//        let contentExtractor = try ContentExtractor(source: view)
//        let view = try contentExtractor.extractContent(environmentObjects: medium.environmentObjects)
        return try Inspector.viewsInContainer(view: view, medium: medium)
    }
}

but now the tree is not traversed properly, I'm currently trying to debug it further to understand why. Is it theoretically possible to fulfil my task with doing some additional changes? The current real time view state can be somehow fetched?

If you will have some time, could you point me in the right direction?

Thanks again!

nalexn commented 8 months ago

Hey - I've been asked about this a couple of times in the past - the real view hierarchy being rendered by SwiftUI in runtime is fully private, ViewInstector isn't able to access it. Instead, it creates its own virtual copy and operates on it. While this is somewhat useful for tests, it doesn't give much for a live-running app.