Question

In my quest to update a Core Data model within my iOS project, I'm querying a server for JSON objects that correspond - to some extent - with the managed entities of my model. The end result I'm striving for is a reliable update solution from JSON output.

For the examples in this question, I'll name the core data managed object existingObj and the incoming JSON deserialized dictionary updateDict. The tricky part is dealing with these facts:

  1. Not all properties of the existingObj are present in the updateDict
  2. Not all properties of the updateDict are available in the extistingObj.
  3. Not all types of existingObj's properties match the JSON deserialized properties. (some strings may need a custom Objective-C wrapper).
  4. updateDict may contain values for keys that are uninitialized (nil) in existingObj.

This means that while iterating through the updated dictionaries, there has to be some testing of properties back and forth. First I have to test whether the properties of the updateDict exist in existingObj, then I set the value using KVC, like so:

// key is an NSString, e.g. @"displayName"
if ([existingObj respondsToSelector:NSSelectorFromString(key)) {
    [existingObj setValue:[updateDict objectForKey:key] forKey:key];
}

Although this part works, I don't like the fact that I'm actually testing for displayName as a getter, while I'm about to call the setDisplayName: setter (indirectly via KVC). What I'd rather to is something like [existingObj hasWritablePropertyWithName:key], but something that does this I can't find.

This makes for subquestion A: How does one test for a property setter, if you only have the property's name?

The next part is where I'd like to automate the property identification based on their types. If both the updateDict and the existingObj have an NSString for key @"displayName", setting the new value is easy. However, if the updateDict contains an NSString for key @"color" that is @"niceShadeOfGreen", I'd like to transform this into the right UIColor instance. But how do I test the type of the receiving property in existingObj so I know when to convert values and when to simply assign? I was hoping for something along the lines of typeOfSelector:

if ([existingObj typeOfSelector:sel] == [[updateDict objectForKey:key] class]) {
     // regular assignment
} else {
     // perform custom assignment
}

Of course this is boguscode. I can't rely on testing the type of the existingObj-property's value, for it may be unitialized or nil.

Subquestion B: How does one test for the type of a property, if you only have the property's name?

I guess that's it. I figured this must be a dupe of something that's already on here, but I couldn't find it. Maybe you guys can?
Cheers, EP.

P.S. If you'd have a better way to synchronize custom Objective-C objects to deserialized JSON objects, please do share! In the end, the result is what counts.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top