1

How do you fetch an object using its UUID? I have an object (TimeCode) with an id attribute that is of type UUID in the xcdatamodel file. I want to fetch an object of this type from CoreData by using this id attribute in the standard NSPredicate, but I got a compilation error saying that I had to use the id as a CVarArg. But at runtime, when I actually called the function, the program crashed as the ObjectIdentifier type couldn't be cast to CVarArg.

Here is the full code:

func fetchTimeCode(id: ObjectIdentifier) -> TimeCode? {
        var timeCodes = [TimeCode]()
        
        let request: NSFetchRequest<TimeCode> = TimeCode.fetchRequest()
        
        request.predicate = NSPredicate(format: "id ==  %@", id as! CVarArg)
        
        do {
            timeCodes = try self.moc.fetch(request)
        }
        catch let error as NSError {
            print("Error fetching for editing.")
            print(error)
        }
        
        print("fetch request id: \(id)")
        
        return timeCodes.first
    }

Any help would be much appreciated. I looked seemingly everywhere and couldn't find any answers. Right now it seems like the best solution is to just store the id as a string, but that doesn't seem especially elegant. What is the point of having a UUID for your object if you can't easily fetch the object using it?

Update: Here is my code for the TimeCodeViewModel class.

class TimeCodeViewModel: Identifiable {
    var id: ObjectIdentifier
    var fullName = ""
    
    
    init(timeCode: TimeCode) {
        self.id = timeCode.id
        self.fullName = timeCode.fullName!
    }
    
    // class methods
}
greatxp117
  • 57
  • 11
  • Possibly helpful: https://stackoverflow.com/a/68412528/1187415 – Martin R Sep 07 '21 at 02:27
  • Maybe `request.predicate = NSPredicate(format: "id == %@", argumentArray: [id])`? But I would have keep `UUID` and not `ObjectIdentifier`. – Larme Sep 07 '21 at 08:37
  • What exactly is `ObjectIdentifier`? It's not part of the framework. Not everything can be typecast to `CVarArg`. – Tom Harrington Sep 07 '21 at 16:14
  • I get the id for the function call from a ViewModel that I created for the object. In order to get the ```id``` from the original ```TimeCode``` type into the ```TimeCodeViewModel```, I had to make the ViewModel id type ```ObjectIdentifier```, otherwise I'd get an error saying that UUID is a get only property (i.e. I can't assign the id from my TimeCode to my TimeCodeViewModel without making it ```ObjectIdentifier``` type). I guess this is my real issue. – greatxp117 Sep 08 '21 at 03:59

1 Answers1

4

In my case it works with a following predicate:

func getItem(with id: UUID?) -> Item? {
    guard let id = id else { return nil }
    let request = Item.fetchRequest() as NSFetchRequest<Item>
    request.predicate = NSPredicate(format: "%K == %@", "id", id as CVarArg)
    guard let items = try? context.fetch(request) else { return nil }
    return items.first
}

More importantly, I am using UUID (the same case is in the answer suggested by Martin), not ObjectIdentifier. It is definitely possible to fetch items based on UUID.

Please try to change a parameter type in your function to UUID

Viktor Gavrilov
  • 830
  • 1
  • 8
  • 13
  • Thank you! I figured it would be this easy, I guess I got jumbled up because of an error I was getting elsewhere in my code that made me use ```ObjectIdentifier``` instead of ```UUID``` as the type. I detailed it in my reply to Tom Harrington, I would really appreciate it if you gave your thoughts on it. – greatxp117 Sep 08 '21 at 04:04
  • @greatxp117 could you add some code from ``TimeCodeViewModel`` where you have a problem? – Viktor Gavrilov Sep 08 '21 at 05:34
  • yesI have updated my post to include my code for the ```TimeCodeViewModel```. I was getting the error when I try to assign ```self.id``` from ```timeCode.id``` if ```self.id``` was type ```UUID```. However, it worked when ```self.id``` was type ```ObjectIdentifier```, so I figured that was the way to do it. – greatxp117 Sep 11 '21 at 05:37