Home > Enterprise >  Swift Combine: Could not extract a String from KeyPath Swift.KeyPath
Swift Combine: Could not extract a String from KeyPath Swift.KeyPath

Time:10-21

I'm trying to observer any changes in object in the core data instance. Here is my code:

class MyClass {
    @objc dynamic var str: String?
}

final class Article: NSObject {
    @objc dynamic var title: String?
    @objc dynamic var summary: String?
    var myVar: MyClass?
}

Here is were I'm implementing the observers:

func update(article: Article) {
    titleSubscription = article.publisher(for: \.title).sink { value in
        print(value)
    } receiveValue: { _ in
        print("I got something")
    }
    summarySubscription = article.publisher(for: \.myVar?.str).sink{ _ in
        
    } receiveValue: { _ in
        
    }
}

But I'm getting this error:

Thread 1: Fatal error: Could not extract a String from KeyPath Swift.KeyPath<Examples.Article, Swift.Optional<Swift.String>>

enter image description here

Any of you knows why I'm getting this error or if there is any work around ?

I'll really appreciate your help.

CodePudding user response:

You are trying to create a publisher that uses key-value observing. Key-value observing is a feature of the Objective-C runtime. You have exposed the properties title and summary to the Objective-C runtime by putting @objc and dynamic on them. myVar, however, is a plain instance variable, not a observable property. So the key-value coding system can't find it and at runtime you get an error.

The documentation at

https://developer.apple.com/documentation/swift/cocoa_design_patterns/using_key-value_observing_in_swift/

says

Annotate a Property for Key-Value Observing

Mark properties that you want to observe through key-value observing with both the @objc attribute and the dynamic modifier.

In addition, to participate in key-value coding, MyClass will also have to be available to Objective-C and must have the properties you wish to access from key-key value observing marked too:

class MyClass : NSObject {
    @objc dynamic var str: String?
}

final class Article: NSObject {
    @objc dynamic var title: String?
    @objc dynamic var summary: String?
    @objc dynamic var myVar: MyClass?
}
  • Related