Resolver icon indicating copy to clipboard operation
Resolver copied to clipboard

Can't use existential 'any' with InjectedObject property wrapper

Open mobileuidev opened this issue 2 years ago • 4 comments

I can't use the existential 'any' keyword with @InjectedObject property wrapper, the fired error is: Type 'any Test' cannot conform to 'ObservableObject'

the example is as follows:

protocol Test: ObservableObject {
    
}

class MyViewModel: Test {
    
}

struct MyView: View {
    @InjectedObject var viewModel: any Test //<---- the error fires here
    
    var body: some View {
        Text("Hello")
    }
}

mobileuidev avatar Mar 28 '23 11:03 mobileuidev

You might take a look at the following.

https://medium.com/swlh/did-swiftui-just-kill-protocol-oriented-programming-c09c2787172

Making the VM a protocol is a bad idea, and suffers from a plethora of problems.

https://stackoverflow.com/questions/59503399/how-to-define-a-protocol-as-a-type-for-a-observedobject-property

hmlongco avatar Mar 28 '23 23:03 hmlongco

I have read the article and the SO question, the article strongly recommends to inject a loader object into the view model and this loader can be safely a protocol not the view model itself, which I exactly did in my real project, but the view model itself, in a real world example, is not a simple load and set published properties, it may have lots of other functions that need to be tested, giving this difficulty of using the view model as a protocol I can only mock the view model using class inheritance which's not the best way for mocking. I can't use generics too to workaround this issue, as it forces me to specialize the view model class type once I define the view causing lots of other view issues in my complex project.

mobileuidev avatar Mar 29 '23 10:03 mobileuidev

This is really an issue with Swift and associated types and there really isn't a lot I can do about it other than say, "Don't do that."

If the VM is as complex as you say, then IMHO that's even more reason to follow the advice I gave in the article so that you can test the code appropriately. A VM doesn't exist in a vacuum. If you change its dependencies and/or parameters then you should be able to mock any associated behavior.

hmlongco avatar Mar 29 '23 13:03 hmlongco

Thank you for the advice anyway.

mobileuidev avatar Mar 30 '23 07:03 mobileuidev