Reputation: 56948
If I have an NSManagedObject I've fetched from a context, how can I create an NSDictionary out of its dynamic properties without just copying each field into the dictionary explicitly?
If my managed object looks like this, for example:
@implementation Track
@dynamic artist;
@dynamic group;
@dynamic purchase_url;
@dynamic title;
@dynamic file_name;
@dynamic year;
@end
After fetching from the database, in this case, I need an NSDictionary with the same properties set to each of those @dynamic properties.
Upvotes: 20
Views: 14146
Reputation: 1226
Note: Swift 4.2
update
let keys = Array(YOUR_MANAGED_OBJECT.entity.attributesByName.keys)
let data:[String: Any] = YOUR_MANAGED_OBJECT.dictionaryWithValues(forKeys: keys)
Upvotes: 3
Reputation: 726
There is a faster way to convert an NSManagedObject to an NSDictionary (from Matthias Bauch response at https://stackoverflow.com/a/5664745/2294824) :
NSArray *keys = [[[myObject entity] attributesByName] allKeys];
NSDictionary *dict = [myObject dictionaryWithValuesForKeys:keys];
Upvotes: 57
Reputation: 450
I think this is what you're actually looking for:
NSEntityDescription *trackEntity = [NSEntityDescription entityForName:[Track entityName] inManagedObjectContext:yourMOC];
then you have access to these dictionaries:
[trackEntity propertiesByName];
[trackEntity relationshipsByName];
[trackEntity attributesByName];
each of these dictionaries will have keys corresponding to the property, and the value will be an NSPropertyDescription.
Upvotes: 7
Reputation: 585
You can achieve your approach by following method:
unsigned int count;
objc_property_t *properties = class_copyPropertyList([CoreDataObject class], &count);
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:16];
for(int i = 0; i < count; i++) {
objc_property_t property = properties[i];
NSString *name = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
id obj = [coreDataObjectInstance valueForKey:name];
if (obj) {
// Skip properties with nil values (optionally you can use: [dictionary setObject:((obj == nil) ? [NSNull null] : obj) forKey:name]; without any if-statement)
[dictionary setObject:obj forKey:name];
}
}
free(properties);
"CoreDataObject" is the core data object you would like to convert into a NSDictionary while "coreDataObjectInstance" is an instance of this core data object. Keep in mind you have to:
#include <objc/runtime.h>
Furthermore, it would be great if you can give us some more insights what you would like to achieve with this idea, maybe there is a different/better solution.
Hope this helps!
Upvotes: 12