I parse some JSON from a web service, this gives me an NSDictionary, I use this dictionary to populated properties on a valueEntity of type NSObject by
[myObject setValuesForKeysWithDictionary:JSONDict];
(myObject has the same property names and types as the dictionary from the JSON parser)
name = name
count = count
startDate = startDate
etc..
Is there a way to go the other way, where I have an NSDictionary that I would like to have "filled" with the properties and their values from an my NSObject subclass. Like I suggest in the title, something along the lines of this:
one way
MyObject *myObject = [[MyObject alloc] init];
[myObject setValuesForKeysWithDictionary:JSONDict];
the other way around
NSMutableDictionary *dict = [myObject makeDictionaryWithObjectProperties];
The reason for this is that I have a valueEntity which, by protocol, my views all conform to, but I would like to populate an NSManagedObject with the values as well. So I thought that using the NSDictionary as an intermediate step I can get around having to do a category on my NSManagedObject that sets each property manually from the value on my object subclassing NSObject.
With a dictionary I can go:
[myManagedObject setValuesForKeysWithDictionary:dict];
I just can't get the dictionary representation back out once I done the above?
Yep, the method is:
- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys
You pass in an array of keys representing the object properties that you're interested in, and get back a dictionary containing the property values.
The NSKeyValueCoding
protocol defines a number of powerful and highly useful methods; it's a great thing to get familiar with.
http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Protocols/NSKeyValueCoding_Protocol/Reference/Reference.html
There's also a very valuable companion guide:
http://developer.apple.com/library/ios/documentation/cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html#//apple_ref/doc/uid/10000107i
Do you really want to get all the properties? Often it doesn't make sense to get all the properties of an object as a dictionary. For example, if an NSManagedObject
contains a relationship, do you want to get it too in the dictionary? If so, how do you want to represent it?
As jlehr said, it's better to feed a set of keys explicitly using dictionaryWithValuesForKeys:
.
That said, using the dreaded Objective-C runtime, you can indeed implement makeDictionaryWithObjectProperties
. Use class_getPropertyList and property_getName. I won't detail how to do that, because if you do follow this approach, you know what you're doing.
By the way, it's very dangerous for you to assign a JSON
object returned from the Internet to an NSManagedObject
using setValuesForKeysWithDictionary:
. Because, if the JSON
object happens to contain an additional key which you don't expect, your code can suddenly crash. So, don't do that.
Another comment: your pseudo-code
NSObject *myObject = [[NSObject alloc] init];
[myObject setValuesForKeysWithDictionary:JSONDict];
doesn't make much sense: yes you can call setValuesForKeysWithDictionary:
against NSObject
, but it will miserably fail, because you can't setValue:forKey:
for any of the entries in JSONDict
to a vanilla NSObject
. I guess you know that, but I'd like to say that explicitly so that a novice who comes across this page won't be fooled.
This guy here used some runtime magic to get all the properties declared on an object and got the dictionary without manually providing the property names.
And there'e also this nice github repo i found, They pretty much do the same trick, but in a nice package. They also have the ability to create a json or plist from an object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With