0

I have a Core Data entity that has an attribute named id:

@NSManaged public var id: Int

As I work with SwiftUI, I am adding support for Identifiable, so then the Core Data entity now conforms to it:

extension Car : Identifiable { }

When I try to compile, I get this error for example when I try to use the id in a Predicate:

NSPredicate(format: "\(#keyPath(Car.id)) == \(id)")

Error:

Ambiguous reference to member 'id'

How can I make the Car entity conform to Identifiable while keeping its already existing attribute id?

zumzum
  • 17,984
  • 26
  • 111
  • 172
  • if I remove `extension Car : Identifiable { }` the error goes away. – zumzum Aug 12 '21 at 18:47
  • I believe you have your own property in your coredata as id and identifiable as well has an id property which is not overridden properly and compiler is confused which one you're referring to? – Takasur Aug 12 '21 at 18:56
  • yes, I have the property like shown on the question. I am not sure how to override the property like you said within the Core Data context... How should I do that? – zumzum Aug 12 '21 at 18:58

2 Answers2

1

I believe the error is caused by the way you use the keypath in your predicate. Use this form instead although it isn't optimal with a hardcoded path/property

NSPredicate(format: "id = \(id)")

Update:

I did some further testing and noticed that if I removed the id property completely then I got an error about @objc

Argument of '#keyPath' refers to non-'@objc' property 'id'

and not that the property didn't exist although I did get such an error when I removed conformance to Identifiable. This makes me wonder if the compiler synthesises a property id from the already existing one that isn't using @NSManaged/@objc.

I use id in several of my entities in one project that also conforms to Identifiable but I don't use id in any predicate so it's no issue for me.

My recommended solution would be to rename the property in the model and declare id as a computed property

@NSManaged public var carId: Int

extension Car : Identifiable {
    public var id: Int {
        carId
    }
}

and then use carId in predicates and otherwise id (one option is to make carId private)

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • I get the same error when using this answer. Still says `Ambiguous reference to member 'id'` – zumzum Aug 12 '21 at 19:20
  • Version 13.0 beta 5 (13A5212g), but, I have the same problem even in Xcode 12.0 and previous 13.0 betas... – zumzum Aug 12 '21 at 19:21
  • yes, I did change the name of `id` to a different name for troubleshooting and that did work. Unfortunately I have a lot entities that use id and it would be a lot of work to rename all the `id`s.... That's why I posted this question with the `while keeping its already existing attribute id` spec... very strange Apple would overlook this. – zumzum Aug 12 '21 at 20:41
  • Yes it’s a bit strange but you can always use the “hardcoded” option. For me it’s like I said not an issue since I don’t have any predicates using `id` – Joakim Danielson Aug 12 '21 at 20:47
  • Yes. That would also require me to change all the predicates... This approach might be what I have to use in the end. Not sure yet. – zumzum Aug 12 '21 at 20:52
  • Not my business really but why do you need to fetch your entities by id, unless this is some external reference it shouldn’t be needed – Joakim Danielson Aug 13 '21 at 06:08
  • External reference…. – zumzum Aug 13 '21 at 13:45
1

I have used NSManagedObjects which conform to Identifiable with predicates successfully.

Try: NSPredicate(format: "id == %@", id as CVarArg)

hidden-username
  • 2,610
  • 3
  • 14
  • 19