Reputation: 5303
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.
Upvotes: 0
Views: 1146
Reputation: 70936
The problem is that addressBookId
is (as you mentioned in a comment) defined as a transformable attribute on the Contact
entity. However (as you also mentioned in a comment) you don't have any custom code to actually transform an ABRecordRef
into something that Core Data knows how to store. With no custom transformer, Core Data is going to try and transform the value by calling encodeWithCoder:
on the value. But ABRecordRef
doesn't conform to NSCoding
, so this fails and your app crashes.
If you want to store the ABRecordRef
in Core Data, you'll need to create an NSValueTransformer
subclass and configure that in your data model. Your transformer would need to convert ABRecordRef
into 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 documents NSValueTransformer
pretty well.
The fact that it's a one-to-many relationship is irrelevant; the problem is that ABRecordRef
can't go into your data store without some transformation.
Upvotes: 3