BluGeni
BluGeni

Reputation: 3454

get the name of the property not the value

I am using core data and have been using code like this:

[self.form setValue:self.comments.text forKey:@"comments"];

I want to put code like this into a loop, all my coredata names are the same as the property name. How can I say forKey:self.comments.name and get the same outcome as above or something like that?

EDIT:

If this is not possible, is there another way to set a ton of values into coredata from properties? I have 50+ attributes and properties alike that need to be set and would like to avoid using what im doing now.

Upvotes: 1

Views: 111

Answers (3)

alex-i
alex-i

Reputation: 5454

One way would be to declare an array of the attributes yourself.

NSArray *attributes = [NSArray arrayWithObjects:..., @"comments", .., nil]; // or a NSSet
for(NSString *attribute in attributes){
    NSString *text = [[self performSelector:NSSelectorFromString(attribute)] text]; // presuming that it's safe to call 'text' on all your properties
    [self.form setValue:text forKey:attribute];
}

Or you can use this if you want all the attributes of your core data model.

Upvotes: 0

imihaly
imihaly

Reputation: 1858

If you really want it, you may use these functions from objc/runtime.h:

objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount) // To get properties declared by a class.
const char *property_getName(objc_property_t property) // To get the name of one property

Something like this:

unsigned int propCount = 0;
objc_property_t *properties = class_copyPropertyList([self class], &propCount);

for(int idx = 0; idx < propCount; idx++) {
    objc_property_t prop = *(properties + idx);
    NSString *key = @(property_getName(prop));
    NSLog(@"%@", key);
}

Upvotes: 3

ryan cumley
ryan cumley

Reputation: 1931

There really is no substitute for reading the docs on CoreData as the patterns for use and syntax will not be obvious at all without a little legwork.

That said, you typically fetch an instance of your NSManagedObject subclass from the data store:

NSManagedObjectContext* moc = [delegate managedObjectContext];
NSEntityDescription* description = [NSEntityDescription entityForName:@"Filter" inManagedObjectContext:moc];
NSSortDescriptor* descriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:description];
[request setSortDescriptors:[NSArray arrayWithObject:descriptor]];
NSError *error;
_enabledFilters = [NSMutableArray arrayWithArray:[moc executeFetchRequest:request error:&error]];
if (error) {
    NSLog(@"%@",error.localizedDescription);
}

In this example I now have an array of instances of my NSManagedObject called "Filter"

Then you can select the appropriate instance to reference, and access all of it's attributes with simple dot syntax.

Filter* thisFilter = (Filter*)[_displayFilters objectAtIndex:indexPath.row];
cell.label.text = thisFilter.name;
cell.label.backgroundColor = [UIColor clearColor];
NSString*targetName = thisFilter.imageName;
UIImage *image = [UIImage imageNamed:targetName];
cell.image.image = image;

Now I've taken info from my persistent data store, and used it within my app.

Going the other way and writing to an instance within your data store is only slightly different, in that you directly set the attributes of an instance of your NSManagedObject subclass, and then call save on the context to push any changes down to the store.

TL;DR - you owe it to yourself to spend an hour or two with the CoreData docs...

Upvotes: 0

Related Questions