7

I am replacing some CoreData code within my iOS App to use the new SwiftData framework. In my original code, I was saving a CoreData object URI in UserDefaults for a quick bookmark. This allowed me to easily fetch specific object I needed directly.

e.g.

model.objectID().uriRepresentation().absoluteString

While investigating a SwiftData solution, I came across this objectID property on SwiftData models, which is of type PersistentIdentifier, which seems to do what I want. But there doesn't seem to a straight forward way to bookmark this value. PersistentIdentifier conforms to the "Codeable", which I could save to UserDeafaults, by converting it to Data, but when I attempt to do that, the returned value doesn't include any of the necessary data, just an empty values. This is what is created when encoding the id or objectID of the Model object.

"{\"implementation\":{}}"

How can I accomplish this with the new SwiftData framework?

3
  • 1
    To me it looks like the encode (and decode?) functionality hasn't been implemented yet for PersistentIdentifier. I can clearly see in the debugger that the objectID property contains data but I get the same empty result when I encode it. Commented Jun 19, 2023 at 19:57
  • Yep. I saw the same thing. I curious why or how since it seems to be using standard Swift foundation types. I guess they are not using the compiler generated Encode/Decode implementation and just have empty functions or something?
    – DookieMan
    Commented Jun 19, 2023 at 20:12
  • My guess is that something is expected to change in the structure or data of the type so they have created this dummy encoding so we won’t encode data that we later on can’t decode. Commented Jun 20, 2023 at 6:39

2 Answers 2

2

Until Apple provides this, here is a temporary solution that seems to work well:

extension PersistentIdentifier {

    public func uriRepresentation() -> URL? {
        if let encoded = try? JSONEncoder().encode(self),
           let dictionary = try? JSONSerialization.jsonObject(with: encoded) as? [String: Any],
           let implementation = dictionary["implementation"] as? [String: Any],
           let uriRepresentation = implementation["uriRepresentation"] as? String {
            return URL(string: uriRepresentation)
        } else {
            return  nil
        }
    } }

FYI, unlike the Core Data method, I made the result of my uriRepresentation extension an Optional to suit the needs of my App.

1
  • Obviously this is now obsolete since PersistentIdentifier works as expected with Codable.
    – Chuck H
    Commented Oct 7, 2023 at 21:39
0

Looks like in Xcode 15 Beta 5 Codable is working as expected.

Not the answer you're looking for? Browse other questions tagged or ask your own question.