Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type 'any ProtocolName' cannot conform to '(ProtocolName's Inherited Protocol)' [duplicate]

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()
like image 290
stevenyuser Avatar asked Mar 06 '26 05:03

stevenyuser


1 Answers

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())
like image 64
Scott Thompson Avatar answered Mar 08 '26 21:03

Scott Thompson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!