I am having troubles with the relationship I have setup in CoreData. Its one to many, a Customer can have many Contact, these contacts are from address book.
My model it looks like this:
Customer <---->> Contact
Contact <-----> Customer
Contact.h
@class Customer;
@interface Contact : NSManagedObject
@property (nonatomic, retain) id addressBookId;
@property (nonatomic, retain) Customer *customer;
@end
Customer.h
@class Contact;
@interface Customer : NSManagedObject
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSSet *contact;
@end
@interface Customer (CoreDataGeneratedAccessors)
- (void)addContactObject:(Contact *)value;
- (void)removeContactObject:(Contact *)value;
- (void)addContact:(NSSet *)values;
- (void)removeContact:(NSSet *)values;
@end
And trying save with:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
Customer *customer = (Customer *)[NSEntityDescription insertNewObjectForEntityForName:@"Customer" inManagedObjectContext:context];
[customer setValue:name forKey:@"name"];
for (id contact in contacts) {
ABRecordRef ref = (__bridge ABRecordRef)(contact);
Contact *contact = [NSEntityDescription insertNewObjectForEntityForName:@"Contact" inManagedObjectContext:context];
[contact setValue:(__bridge id)(ref) forKey:@"addressBookId"];
[customer addContactObject:contact];
}
NSError *error;
if ([context save:&error]) { // <----------- ERROR
// ...
}
With my code, I have this error:
-[__NSCFType encodeWithCoder:]: unrecognized selector sent to instance 0x9c840c0
*** -[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType encodeWithCoder:]: unrecognized selector sent to instance 0x9c840c0'
Any suggestions would be appreciated.
The problem is that
addressBookIdis (as you mentioned in a comment) defined as a transformable attribute on theContactentity. However (as you also mentioned in a comment) you don’t have any custom code to actually transform anABRecordRefinto something that Core Data knows how to store. With no custom transformer, Core Data is going to try and transform the value by callingencodeWithCoder:on the value. ButABRecordRefdoesn’t conform toNSCoding, so this fails and your app crashes.If you want to store the
ABRecordRefin Core Data, you’ll need to create anNSValueTransformersubclass and configure that in your data model. Your transformer would need to convertABRecordRefinto one of the types Core Data knows. I haven’t worked with the address book API enough to advise on the details of this, but Apple documentsNSValueTransformerpretty well.The fact that it’s a one-to-many relationship is irrelevant; the problem is that
ABRecordRefcan’t go into your data store without some transformation.