I have a ProtocolName that conforms to ObservableObject. I then have ClassName that conforms to ProtocolName.
However, when I try to use @ObservedObject serviceName: ProtocolName = ClassName, it fails to build with the following message: "Type 'any ProtocolName' cannot conform to 'ObservableObject'"
What am I doing wrong and how can I fix this?
Example:
protocol ProtocolName: ObservableObject {
let random: String
}
class ClassName: ProtocolName {
let random: String
}
@ObservedObject serviceName: ProtocolName = ClassName()
When you write a line like this:
@ObservedObject var observeMe: ProtocolName
You are saying that observeMe is a box that can contain any kind of thing that conforms to the ProtocolName protocol"
The type of that box is any ProtocolName it's called an existential.
But the box itself does NOT conform to ProtocolName(and by extension does not conform to ObservableObject). The thing inside the box does, but the box itself does not.
So the compiler complains that the existential whose type is any ProtocolName is not an ObservableObject
You can make the box even more obvious and explicit using the any ProtocolName syntax:
import SwiftUI
import Combine
protocol ProtocolName: ObservableObject {
var someValue: Int { get }
}
class MyClass: ProtocolName {
@Published var someValue: Int = 42
}
struct SomeStruct : View {
@ObservedObject var observeMe: any ProtocolName = MyClass()
var body: some View {
Text("Hello.")
}
}
And you'll still see the error.
To solve the problem your @ObservedObject has to be a concrete type that conforms to ProtocolName:
import SwiftUI
import Combine
protocol ProtocolName: ObservableObject {
var someValue: Int { get }
}
class MyClass: ProtocolName {
@Published var someValue: Int = 42
}
struct SomeStruct : View {
@ObservedObject var observeMe: MyClass = MyClass()
var body: some View {
Text("Hello.")
}
}
let myView = SomeStruct()
Or you can add a type parameter to your view so that when the view is created there is a specific type that conforms to the protocol that is used for the view:
import SwiftUI
import Combine
protocol ProtocolName: ObservableObject {
var someValue: Int { get set }
}
class MyClass: ProtocolName {
@Published var someValue: Int = 42
}
struct SomeStruct<T : ProtocolName> : View {
@ObservedObject var observeMe:T
var body: some View {
Text("Hello.")
Button(action: {observeMe.someValue = 3}) {
Text("Button")
}
}
}
let myView = SomeStruct(observeMe: MyClass())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With