mfaani
mfaani

Reputation: 36317

update key values of NSManagedObjects safely

I'm trying to pass key value pairs and have the attributes updated through a loop.

func update(storableClass : NSManagedObject.Type, id: ID, fields: [String : Any]) throws {

    // retreive manaagedObject
    for (key, value) in fields {
        manaagedObject.setValue(value, forKey: key)
    }
}

Apparently the setValue(_:forKey:) will throw an exception if the key doesn't exist.

From what I've learned you're not to catch an Objective-C exception in Swift.

Is there any safe way to update core data properties through a dictionary?

I know I can have a function like below:

func update(storableClass : ManagedObject.Type, id: ID, closure: (ManagedObject) -> ()) throws {}

and then call it as such:

update(storableClass: UserEntity.self, id: "123123", closure: { userEntity in
    userEntity.name = "new name" 
})

I like to have both options...and any other safe/swifty option...

Upvotes: 2

Views: 496

Answers (1)

Tom Harrington
Tom Harrington

Reputation: 70966

I've had this exact problem. Here's what you do.

With Core Data, you can easily find out what property names are valid for the object. Get a reference to the managed object's entity, and then ask the entity for the properties. You'd use managedObject.entity.propertiesByName. The result is a dictionary where the keys are valid properties. The code would be something like

let properties = managedObject.entity.propertiesByName
for (key, value) in fields {
    if properties[key] != nil {
        managedObject.setValue(value, forKey: key)
    } else {
        print("Unknown key: \(key)")
    }
}

This is fine as long as value is the right type. If you start getting bogus data types in JSON, you have a more complex problem to solve.

For relationships, do the same thing with managedObject.entity.relationshpsByName.

Upvotes: 4

Related Questions