5

I had a class like this:

class ObjectA:ObservableObject { 
  @Published var type:ObjectSheetType = .none
}

and I was using a class like this to process instances of this kind of object:

class ProcessObject {

  @ObservedObject private var object:ObjectA

  init(object:ObjectA) {
    self.object = object
  }

  process() {
    if object.type == .big {
     // bla bla
    }
    ...
  }

Then I have decided to add another class:

class ObjectB:ObservableObject { 
  @Published var type:ObjectSheetType = .none
}

and a protocol

protocol ObjectProtocol {
  var type:ObjectSheetType { get set }
}

This protocol was added to both classes: ObjectA and ObjectB.

Then the class ProcessObject was modified to accept objects of both kinds:

class processObject<T:ObjectProtocol, ObservableObject > {

  @ObservedObject private var object:T

  init(object:T) {
    self.object = object
  }

Error: Referencing subscript 'subscript(dynamicMember:)' requires wrapper 'ObservedObject.Wrapper' Insert '$' Value of type 'T' has no dynamic member 'object' using key path from root type 'T'

error pointing to

if object.type == .big {

but also Xcode wants me to use $ in front of every published properties of object?

How do I solve this?

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
Duck
  • 34,902
  • 47
  • 248
  • 470
  • Does this answer your question https://stackoverflow.com/a/59504489/12299030? BTW @ObservedObject has no sense inside class, it is valid only inside SwiftUI view. – Asperi Jul 09 '21 at 12:14
  • May be helpful for somebody, as of xcode14.1, this error is also returned if there is a typo in the variable name. In the example above `if object.types == .big {` returns this extremely confusing error... – jalone Apr 19 '23 at 11:51

1 Answers1

3

All you need to do is to fix the protocol conformance of T because now ObservableObject is seen as another generic type and not the protocol.

Use & to say that T should conform to both protocols

class ProcessObject<T: ObjectProtocol & ObservableObject> {

}

Another way is to say that ObjectProtocol inherits from ObservableObject and then only use ObjectProtocol in all the conform declarations

protocol ObjectProtocol: ObservableObject {
    var type:ObjectSheetType { get set }
}

but that changes what ObjectProtocol is and you may not want that tight coupling between the two protocols

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • Thanks. Can you explain your last phrase: `but that changes what ObjectProtocol is and you may not want that tight coupling between the two protocols` ? – Duck Jul 09 '21 at 13:07
  • I always thought the comma on the <> was saying both. – Duck Jul 09 '21 at 13:10