Reputation: 25
I'm inheriting a project from someone else and it was created in an older version of Xcode. Upon upgrading I've found a few things I've had to fix, but this one is stumping me.
I have a CoreData model with classes generated by Xcode (NSManagedObject). I have a Meeting object which contains a speaker attribute using the Speaker class. The relationships are all in place but upon the first attempt at assigning a meeting instance's speaker attribute I get the following:
2016-05-26 16:32:46.276 SignMeIn[7829:316171] -[NSKnownKeysDictionary1 setSpeaker:]: unrecognized selector sent to instance 0x7a9042b0
2016-05-26 16:32:46.288 SignMeIn[7829:316171] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSKnownKeysDictionary1 setSpeaker:]: unrecognized selector sent to instance 0x7a9042b0'
*** First throw call stack:
(
0 CoreFoundation 0x033ea494 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x02ea4e02 objc_exception_throw + 50
2 CoreFoundation 0x033f4253 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0332989d ___forwarding___ + 1037
4 CoreFoundation 0x0332946e _CF_forwarding_prep_0 + 14
5 SignMeIn 0x000be242 +[CoreDataManager addSpeakerWithDictionary:forMeeting:] + 1458
6 SignMeIn 0x000bf6b6 +[CoreDataManager insertMeetingsFromArray:] + 902
7 SignMeIn 0x000b7f5b -[SyncView request:hasBeenTerminatedWithSuccess:forServiceMethod:] + 2203
8 SignMeIn 0x0009c0f6 __91+[OnsiteAttendeeAPI callApiMethod:isPost:parametersDictionary:delegate:shouldStartRequest:]_block_invoke.101 + 118
9 SignMeIn 0x00070425 -[ASIHTTPRequest reportFinished] + 213
10 libobjc.A.dylib 0x02eb9059 -[NSObject performSelector:withObject:] + 70
11 Foundation 0x023eb5f8 __NSThreadPerformPerform + 323
12 CoreFoundation 0x032fce5f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
13 CoreFoundation 0x032f2aeb __CFRunLoopDoSources0 + 523
14 CoreFoundation 0x032f1f08 __CFRunLoopRun + 1032
15 CoreFoundation 0x032f1846 CFRunLoopRunSpecific + 470
16 CoreFoundation 0x032f165b CFRunLoopRunInMode + 123
17 GraphicsServices 0x04a71664 GSEventRunModal + 192
18 GraphicsServices 0x04a714a1 GSEventRun + 104
19 UIKit 0x00e64eb9 UIApplicationMain + 160
20 SignMeIn 0x000534f2 main + 178
21 libdyld.dylib 0x040aaa25 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
My Meeting class has a speaker attribute of type Speaker *, and everything in the .m has @dynamic statements which should create the getter/setters.
Here's the code:
+ (void) addSpeakerWithDictionary: (NSDictionary *) speakerDict forMeeting: (Meeting *) aMeeting
{
int speakerID = [speakerDict[@"id"] intValue];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"identification = %d AND %@ IN meeting", speakerID, aMeeting];
NSArray *speakersArray = [CoreDataManager fetchObjects:@"Speaker" withSortDescriptors:nil andPredicate:predicate];
if (speakersArray.count == 0)
{
Speaker *speaker = [NSEntityDescription insertNewObjectForEntityForName:@"Speaker" inManagedObjectContext:[CoreDataManager managedObjectContext]];
speaker.degree = speakerDict[@"degree"];
speaker.firstName = speakerDict[@"firstName"];
speaker.identification = @(speakerID);
speaker.lastName = speakerDict[@"lastName"];
speaker.preTitle = speakerDict[@"preTitle"];
speaker.version = speakerDict[@"version"];
aMeeting.speaker = speaker;
}
Any help is greatly appreciated. Thanks!
Edit: Here's the calling method(s):
+ (void) insertMeetingsFromArray: (NSArray *) meetingsArray
{
for (NSDictionary *dict in meetingsArray)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"identification = %d AND user = %@", [dict[@"id"] intValue], SessionManagerInstance.loggedUser];
NSArray *meetArray = [CoreDataManager fetchObjects:@"Meeting" withSortDescriptors:nil andPredicate:predicate];
if (meetArray.count)
{
Meeting *meeting = meetArray[0];
[CoreDataManager addSpeakerWithDictionary:dict[@"speaker"] forMeeting:meeting];
}
else
[CoreDataManager insertMeetingWithDictionary:dict];
}
[CoreDataManager saveContext];
}
And
+ (void) insertMeetingWithDictionary: (NSDictionary *) dict
{
// NSLog(@"dict: %@", dict);
Meeting *meeting = [NSEntityDescription insertNewObjectForEntityForName:@"Meeting" inManagedObjectContext:[CoreDataManager managedObjectContext]];
meeting.brand = dict[@"brand"];
meeting.category = dict[@"category"];
meeting.city = dict[@"city"];
meeting.closed = @([dict[@"closed"] boolValue]);
meeting.date = [Utilities dateFromDateTime:dict[@"date"]];
meeting.dateString = dict[@"dateString"];
meeting.identification = @([dict[@"id"] intValue]);
meeting.initiative = dict[@"initiative"];
meeting.location = dict[@"location"];
meeting.notes = dict[@"notes"];
meeting.state = dict[@"state"];
meeting.timeZone = dict[@"timeZone"];
meeting.title = dict[@"title"];
meeting.type = dict[@"type"];
[meeting setUser:SessionManagerInstance.loggedUser];
[CoreDataManager addOrInsertRepWithDictionary:dict[@"rep"] forMeeting:meeting];
[CoreDataManager addSpeakerWithDictionary:dict[@"speaker"] forMeeting:meeting];
[CoreDataManager insertGroupsFromArray:dict[@"questiongroups"] forMeeting:meeting];
}
Updated with classes:
Meeting.h (using @dynamic in .m)
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Attendee, Group, Rep, Speaker, User;
@interface Meeting : NSManagedObject
@property (nonatomic, retain) NSString * brand;
@property (nonatomic, retain) NSString * category;
@property (nonatomic, retain) NSString * city;
@property (nonatomic, retain) NSNumber * closed;
@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) NSString * dateString;
@property (nonatomic, retain) NSNumber * identification;
@property (nonatomic, retain) NSString * initiative;
@property (nonatomic, retain) NSString * location;
@property (nonatomic, retain) NSNumber * needsToBeSubmitted;
@property (nonatomic, retain) NSString * notes;
@property (nonatomic, retain) NSString * state;
@property (nonatomic, retain) NSString * timeZone;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSString * transactionId;
@property (nonatomic, retain) NSString * type;
@property (nonatomic, retain) NSSet *attendees;
@property (nonatomic, retain) NSSet *groups;
@property (nonatomic, retain) Rep *rep;
@property (nonatomic, retain) Speaker *speaker;
@property (nonatomic, retain) User *user;
@end
@interface Meeting (CoreDataGeneratedAccessors)
- (void)addAttendeesObject:(Attendee *)value;
- (void)removeAttendeesObject:(Attendee *)value;
- (void)addAttendees:(NSSet *)values;
- (void)removeAttendees:(NSSet *)values;
- (void)addGroupsObject:(Group *)value;
- (void)removeGroupsObject:(Group *)value;
- (void)addGroups:(NSSet *)values;
- (void)removeGroups:(NSSet *)values;
@end
Speaker.h (using @dynamic in .m)
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Speaker : NSManagedObject
@property (nonatomic, retain) NSString * degree;
@property (nonatomic, retain) NSString * firstName;
@property (nonatomic, retain) NSNumber * identification;
@property (nonatomic, retain) NSString * lastName;
@property (nonatomic, retain) NSString * preTitle;
@property (nonatomic, retain) NSString * version;
@property (nonatomic, retain) NSSet *meeting;
@end
@interface Speaker (CoreDataGeneratedAccessors)
- (void)addMeetingObject:(NSManagedObject *)value;
- (void)removeMeetingObject:(NSManagedObject *)value;
- (void)addMeeting:(NSSet *)values;
- (void)removeMeeting:(NSSet *)values;
@end
Upvotes: 1
Views: 1126
Reputation: 1117
Make sure current Core Data model have the right property.
I ran into a similar problem with Core Data where I was getting an unrecognized selector with a setter method error. I accidentally renamed the attribute in my current Core Data model a different name than my Core Data class.
Upvotes: 0
Reputation: 70946
The mention of NSKnownKeysDictionary1
almost certainly means that this line:
[CoreDataManager fetchObjects:@"Meeting" withSortDescriptors:nil andPredicate:predicate];
...is doing a fetch request where the result type is NSDictionaryResultType
. That would mean that meetArray[0]
is a dictionary, not a managed object. It won't have a setSpeaker
method, which causes the error you're seeing.
You could change the fetch request to return managed objects, unless you need them to be dictionaries for some reason. But you can't use dictionaries like this.
Upvotes: 2