I am receiving the following response from my REST Server.
{
id: 1,
model_id: 1,
plant_id: 1,
users: [
2,
9
]
}
To which I am trying to map the following model:
#property (nonatomic, retain) Model *model;
#property (nonatomic, retain) Plant *plant;
#property (nonatomic, retain) NSSet *expertUsers;
and "expertUsers" is a set of objects, based of a class called "User".
Now, I am trying to follow the same approach I have used in the past to connect users to objects, without having the full object. I have been using the following solution, and it works great for single objects.
[pictureMapping addConnectionForRelationship:#"lastModifiedBy" connectedBy:#{ #"lastModifiedByID": #"identifier" }];
However, how can I replicate the same thing, but this time with an array of IDs?
I would need something like this:
[modelExperts addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"users" toKeyPath:#"expertUsers" withMapping:userMapping **addConnectionForRelationship:#"lastModifiedBy" connectedBy:#{ #"lastModifiedByID": #"identifier" }**]];
EDIT #1:
Here is my current Core Data model:
#interface Cell : NSManagedObject
#property (nonatomic, retain) NSNumber *identifier;
#property (nonatomic, retain) NSSet *managers; // To Many Users
#end
#interface User : NSManagedObject
#property (nonatomic, retain) NSNumber *identifier;
#end
RKEntityMapping *cellMapping = [RKEntityMapping mappingForEntityForName:#"Cell" inManagedObjectStore:managedObjectStore];
cellMapping.identificationAttributes = #[#"identifier"];
NSEntityDescription *cellManagersEntityDescription = [NSEntityDescription entityForName:#"Cell" inManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
NSRelationshipDescription *userManagersRelationshipDescription = [cellManagersEntityDescription relationshipsByName][#"managers"]; // To many relationship for the `User` entity
RKConnectionDescription *cellManagersConnection = [[RKConnectionDescription alloc] initWithRelationship:userManagersRelationshipDescription attributes:#{ #"managers": #"identifier" }];
[cellMapping addConnection:cellManagersConnection];
Here is my Rest JSON answer for Cell:
{
id: 1,
managersIDs: [
2
],}
However, I keep getting the following:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot connect relationship: invalid attributes given for source entity 'Cell': managers'
*** First throw call stack:
(
0 CoreFoundation 0x03c646f4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x02df38b6 objc_exception_throw + 44
2 CoreFoundation 0x03c64558 +[NSException raise:format:arguments:] + 136
3 Foundation 0x029d45ee -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 Poka 0x001db61f -[RKConnectionDescription initWithRelationship:attributes:] + 1279
5 Poka 0x0000bdf3 -[APIConnector setupMapping] + 12451
6 Poka 0x000089ef -[APIConnector init] + 159
7 Poka 0x001863da -[IJContext createClassInstanceFromRegistration:withProperties:] + 186
8 Poka 0x00184f12 -[IJContext instantiateClass:withProperties:] + 594
9 Poka 0x00186de0 +[NSObject(Injective) injectiveInstantiate] + 96
10 Poka 0x00008275 -[PokaAppDelegate application:didFinishLaunchingWithOptions:] + 309
11 UIKit 0x01b65525 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 309
12 UIKit 0x01b65d65 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1536
13 UIKit 0x01b6a578 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
14 UIKit 0x01b7e57c -[UIApplication handleEvent:withNewEvent:] + 3447
15 UIKit 0x01b7eae9 -[UIApplication sendEvent:] + 85
16 UIKit 0x01b6c1f5 _UIApplicationHandleEvent + 736
17 GraphicsServices 0x048bc33b _PurpleEventCallback + 776
18 GraphicsServices 0x048bbe46 PurpleEventCallback + 46
19 CoreFoundation 0x03bdfe95 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
20 CoreFoundation 0x03bdfbcb __CFRunLoopDoSource1 + 523
21 CoreFoundation 0x03c0a8ac __CFRunLoopRun + 2156
22 CoreFoundation 0x03c09bf3 CFRunLoopRunSpecific + 467
23 CoreFoundation 0x03c09a0b CFRunLoopRunInMode + 123
24 UIKit 0x01b69cad -[UIApplication _run] + 840
25 UIKit 0x01b6bf0b UIApplicationMain + 1225
26 Poka 0x0000810d main + 141
27 libdyld.dylib 0x032db725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException
The class you're looking for is RKConnectionDescription. The code would look something like:
NSEntityDescription *pictureEntity = [NSEntityDescription entityForName:#"Picture" inManagedObjectContext:managedObjectContext];
NSRelationshipDescription *expertUsers = [pictureEntity relationshipsByName][#"expertUsers"]; // To many relationship for the `User` entity
RKConnectionDescription *connection = [[RKConnectionDescription alloc] initWithRelationship:expertUsers attributes:#{ #"users": #"userID" }];
Assuming that your entities are Picture and User and that the User entity has an identity attribute named userID and the Picture entity has an NSArray or NSSet attribute that is named users and contains the identities mapped from users in the JSON.
Then you can add the connection to your pictureMapping.
In your new code, this line is wrong:
RKConnectionDescription *cellManagersConnection = [[RKConnectionDescription alloc] initWithRelationship:userManagersRelationshipDescription attributes:#{ #"managers": #"identifier" }];
Because it is using the managers attribute which holds the entity instances. It should be linking to an attribute that you don't have which holds the identities of the manager entity instances that you want to link to. So:
Add an attribute managerIds
Add a mapping to fill managerIds with the ids from the JSON
Update cellManagersConnection to reference managers
Related
RJobObject * jobObj = [RJobObject new];
RKMappingOperation *mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:jobDictionary destinationObject:jobObj mapping:[RJobObject mapping]];
mappingOperation.dataSource = (id)jobObj;
[mappingOperation start];
jobDictionary structure:
NSDictionary *msg1 = #{
#"id" : #"dfcd",
#"message" : #"ndjfcdfcd"
};
NSDictionary *msg2 = #{
#"id" : #"fjvdfv",
#"message" : #"kjndcdovc"
};
NSDictionary *msg3 = #{
#"id" : #"fce",
#"message" : #"dfcdf"
};
NSArray *msgsArray = [NSArray arrayWithObjects:msg1, msg2,msg3, nil];
NSMutableDictionary * jobDictionary = [NSMutableDictionary dictionaryWithDictionary:#{#"id" : #"Sourabh pant",
#"title": #"http://www.google.com"
}];
[jobDictionary setObject:msgsArray forKey:#"messages"];
/......................................................./
RJobObject is the custom object:
#property (nonatomic) NSString * id;
#property (nonatomic) long long duration;
#property (nonatomic) NSString * title;
#property (nonatomic) NSString * image;
#property (nonatomic) NSString * secret;
#property (nonatomic) NSInteger unreadCount;
#property (nonatomic) NSArray * messages;
This creates a crash inside RRestkit, if the jobDictionary contains messages.If the messages array inside jobDictionary is empty,then the code runs fine.
So to sum up the message array is not being mapped.
Stack trace
2015-11-28 15:59:22.808 Checking Rest Kit[35951:3402596] -
[RJobObject mappingOperation:targetObjectForRepresentation:withMapping:inRelationship:]: unrecognized selector sent to instance 0x79f96270
2015-11-28 16:00:48.987 Checking Rest Kit[35951:3402596] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RJobObject mappingOperation:targetObjectForRepresentation:withMapping:inRelationship:]: unrecognized selector sent to instance 0x79f96270'
*** First throw call stack:
(
0 CoreFoundation 0x018e3a14 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x013a2e02 objc_exception_throw + 50
2 CoreFoundation 0x018ecd63 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0182a6bd ___forwarding___ + 1037
4 CoreFoundation 0x0182a28e _CF_forwarding_prep_0 + 14
5 Checking Rest Kit 0x00142f48 -[RKMappingOperation destinationObjectForMappingRepresentation:parentRepresentation:withMapping:inRelationship:] + 1704
6 Checking Rest Kit 0x00149885 __64-[RKMappingOperation mapOneToManyRelationshipWithValue:mapping:]_block_invoke + 149
7 CoreFoundation 0x018152e9 __53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 73
8 CoreFoundation 0x01815182 -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 162
9 CoreFoundation 0x017ff835 -[NSArray enumerateObjectsUsingBlock:] + 53
10 Checking Rest Kit 0x0014920b -[RKMappingOperation mapOneToManyRelationshipWithValue:mapping:] + 2763
11 Checking Rest Kit 0x0014b4fb -[RKMappingOperation applyRelationshipMappings] + 6283
12 Checking Rest Kit 0x0014d7db -[RKMappingOperation main] + 4075
13 Checking Rest Kit 0x0014c7dd -[RKMappingOperation start] + 45
14 Checking Rest Kit 0x000ab866 -[ViewController jobObjectFromJobDictionary:] + 310
15 Checking Rest Kit 0x000ab6d5 -[ViewController fetchJobFromDbForId:] + 85
16 Checking Rest Kit 0x000ab566 -[ViewController viewDidLoad] + 918
17 UIKit 0x01e3b2ae -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 44
18 UIKit 0x01e3fdce -[UIViewController loadViewIfRequired] + 1384
19 UIKit 0x01e401ed -[UIViewController view] + 35
20 UIKit 0x01cedf94 -[UIWindow addRootViewControllerViewIfPossible] + 69
21 UIKit 0x01cee6b1 -[UIWindow _setHidden:forced:] + 304
22 UIKit 0x01ceea67 -[UIWindow _orderFrontWithoutMakingKey] + 49
23 UIKit 0x01d02118 -[UIWindow makeKeyAndVisible] + 80
24 UIKit 0x01c6a6e7 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4190
25 UIKit 0x01c71cd6 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1989
26 UIKit 0x01c96ee5 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke3218 + 68
27 UIKit 0x01c6e966 -[UIApplication workspaceDidEndTransaction:] + 163
28 FrontBoardServices 0x04c4dc76 __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 71
29 FrontBoardServices 0x04c4d74d __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 54
30 FrontBoardServices 0x04c6b173 -[FBSSerialQueue _performNext] + 184
31 FrontBoardServices 0x04c6b5aa -[FBSSerialQueue _performNextFromRunLoopSource] + 52
32 FrontBoardServices 0x04c6a8a6 FBSSerialQueueRunLoopSourceHandler + 33
33 CoreFoundation 0x017fd6ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
34 CoreFoundation 0x017f338b __CFRunLoopDoSources0 + 523
35 CoreFoundation 0x017f27a8 __CFRunLoopRun + 1032
36 CoreFoundation 0x017f20e6 CFRunLoopRunSpecific + 470
37 CoreFoundation 0x017f1efb CFRunLoopRunInMode + 123
38 UIKit 0x01c6e206 -[UIApplication _run] + 540
39 UIKit 0x01c73bfa UIApplicationMain + 160
40 Checking Rest Kit 0x000af02a main + 138
41 libdyld.dylib 0x03911a21 start + 1
42 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
In Rconnection.m
- (id)destinationObjectForMappingRepresentation:(id)representation parentRepresentation:(id)parentRepresentation withMapping:(RKMapping *)mapping inRelationship:(RKRelationshipMapping *)relationshipMapping {
/* Some Code */
............
if (destinationObject == nil)
{
NSDictionary *dictionaryRepresentation = [representation isKindOfClass:[NSDictionary class]] ? representation : #{ [NSNull null] : representation };
RKMappingMetadata *parentMetadata = [RKMappingMetadata new];
parentMetadata.parentObject = self.destinationObject ?: [NSNull null];
NSArray *metadata = RKInsertInMetadataList(self.metadataList, parentMetadata, nil);
RKMappingSourceObject *sourceObject = [[RKMappingSourceObject alloc] initWithObject:dictionaryRepresentation parentObject:parentRepresentation rootObject:self.rootSourceObject metadata:metadata];
// Crashing Breakpoint below:
destinationObject = [dataSource mappingOperation:self targetObjectForRepresentation:(NSDictionary *)sourceObject withMapping:concreteMapping inRelationship:relationshipMapping];
}
.......
/* Some code */
}
#import <Foundation/Foundation.h>
#import <RestKit/RestKit.h>
#interface RJobObject : NSObject
#property (nonatomic) NSString * id;
#property (nonatomic) long long duration;
#property (nonatomic) NSString * title;
#property (nonatomic) NSString * image;
#property (nonatomic) NSString * secret;
#property (nonatomic) NSInteger unreadCount;
#property (nonatomic) NSArray * messages;
+(RKObjectMapping *)mapping;
#end
This line is incorrect:
mappingOperation.dataSource = (id)jobObj;
because you are giving the operation a plain data model object as a data source (and telling the compiler to like it by casting to id).
When the operation runs it needs some new instances to be created so it can map the content from the JSON dict into them, this is a job the data source is supposed to do. When the operation asks the data source you get a crash because the object you provided as the data source, jobObj, doesn't understand the request.
You need to create and set an appropriate data source that can handle this requirement.
I am trying to find a way to encapsulate the data for a plot and the delegate functions in one class. This will make it much simpler to create multiple plots dynamically based on the number of data sets that I acquire.
To do so, I created a class that includes the x, y data points and CPTScatterPlot object, as well as the standard delegate functions, which are now class methods that access the internal data.
When the object is instantiated, the idea is to pass it the data and the graph object, and the constructor makes "self" the data source.
Here is the code:
// DataScatterPlot.h
#import <Foundation/Foundation.h>
#import "CorePlot-CocoaTouch.h"
#interface DataScatterPlot : NSObject <CPTScatterPlotDataSource>
#property (nonatomic, strong) CPTScatterPlot *CPTScatterPlotObj;
#property (nonatomic, strong) NSMutableArray *x;
#property (nonatomic, strong) NSMutableArray *y;
- (id) initWithGraph: (CPTXYGraph*) graph DataX: (NSMutableArray*) x andDataY: (NSMutableArray*) y;
#end
// DataScatterPlot.m
#import "DataScatterPlot.h"
#implementation DataScatterPlot
-(id) initWithGraph: (CPTXYGraph *)graph DataX:(NSMutableArray *)dataX andDataY:(NSMutableArray *)dataY {
self = [super init];
if ( self != nil ) {
self.CPTScatterPlotObj = [[CPTScatterPlot alloc] init];
self.x = dataX;
self.y = dataY;
self.CPTScatterPlotObj.dataSource = (id<CPTScatterPlotDataSource>) self;
[graph addPlot:self.CPTScatterPlotObj];
}
return self;
}
// Delegate method that returns the number of points on the plot
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
NSLog(#"The count is %lu", (unsigned long)[self.x count]);
return [self.x count];
}
// Delegate method that returns a single X or Y value for a given plot.
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
// For Sigmoid
NSNumber *dataX = [self.x objectAtIndex:index];
NSNumber *dataY = [self.y objectAtIndex:index];
// FieldEnum determines if we return an X or Y value.
switch (fieldEnum) {
case CPTScatterPlotFieldX:
{
return dataX;
}
case CPTScatterPlotFieldY: // Y-Axis
{
return dataY;
}
default:
return [NSNumber numberWithFloat:0];
}
}
#end
When I run the code, I get an "unrecognized selector sent to instance" error, which seems it indicate it is looking for a method that does not exist within the object.
Is there something that I'm doing incorrectly?
Here is the error message:
2015-10-09 12:02:09.743 SigmoidWithCustomDataClass[1192:10285] -[__NSDictionaryI numberOfRecordsForPlot:]: unrecognized selector sent to instance 0x7f9a2bda7fb0
2015-10-09 12:02:10.550 SigmoidWithCustomDataClass[1192:10285] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI numberOfRecordsForPlot:]: unrecognized selector sent to instance 0x7f9a2bda7fb0'
*** First throw call stack:
(
0 CoreFoundation 0x000000010f697c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010f330bb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010f69f0ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010f5f513c ___forwarding___ + 988
4 CoreFoundation 0x000000010f5f4cd8 _CF_forwarding_prep_0 + 120
5 SigmoidWithCustomDataClass 0x000000010eaae44b -[CPTPlot reloadData] + 94
6 SigmoidWithCustomDataClass 0x000000010eaae289 -[CPTPlot drawInContext:] + 36
7 QuartzCore 0x000000010ec1b92b CABackingStoreUpdate_ + 2793
8 QuartzCore 0x000000010ed21933 ___ZN2CA5Layer8display_Ev_block_invoke + 59
9 QuartzCore 0x000000010ed217be _ZN2CA5Layer8display_Ev + 1478
10 QuartzCore 0x000000010ed164d9 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 301
11 QuartzCore 0x000000010ed16561 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 35
12 QuartzCore 0x000000010ec8286e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
13 QuartzCore 0x000000010ec83a22 _ZN2CA11Transaction6commitEv + 462
14 UIKit 0x000000010fcd09ed -[UIApplication _reportMainSceneUpdateFinished:] + 44
15 UIKit 0x000000010fcd16b1 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2648
16 UIKit 0x000000010fcd0095 -[UIApplication workspaceDidEndTransaction:] + 179
17 FrontBoardServices 0x0000000114bb75e5 __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 21
18 CoreFoundation 0x000000010f5cb41c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
19 CoreFoundation 0x000000010f5c1165 __CFRunLoopDoBlocks + 341
20 CoreFoundation 0x000000010f5c0f25 __CFRunLoopRun + 2389
21 CoreFoundation 0x000000010f5c0366 CFRunLoopRunSpecific + 470
22 UIKit 0x000000010fccfb02 -[UIApplication _run] + 413
23 UIKit 0x000000010fcd28c0 UIApplicationMain + 1282
24 SigmoidWithCustomDataClass 0x000000010eaad71f main + 111
25 libdyld.dylib 0x0000000112474145 start + 1
26 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
The plot's datasource is a dictionary. Check the rest of your code and make sure you're not reassigning the datasource anywhere.
I spent few hours trying to solve problems with parent-child core data model. But let's start from the beginning. I've got main context and child context which has .parentContext as the main context.
- (NSManagedObjectContext *)mainContext {
if (!_mainContext) {
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
}
return _mainContext;
}
- (NSManagedObjectContext *)childContext {
if (!_childContext) {
_childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_childContext setParentContext:self.mainContext];
}
return _childContext;
}
Next I create two objects in separated contexts.
Entity2 *entity2 = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Entity2 class])
inManagedObjectContext:_stack.childContext];
Entity1 *entity1 = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Entity1 class])
inManagedObjectContext:_stack.mainContext];
entity1.arg1 = #"ABC";
entity1.arg2 = #"DEF";
Here all is ok.
Then I want to add one object to relationship of another, no matter if I try to add entity1 to entity2 or vice versa.
[entity1 setEntity2:entity2];
In article of Multi-Context Core Data | Cocoanetics I read that I should perform block with save operation because object's don't know each other. So it look like this:
[_stack.childContext performBlock:^{
NSError *error;
if (![_stack.childContext save:&error]) {
NSLog(#"Error: %#", error);
}
[_stack.mainContext performBlock:^{
NSError *error;
if (![_stack.mainContext save:&error]) {
NSLog(#"Error: %#", error);
}
[entity1 setEntity2:entity2];
}];
}];
But wherever I put [entity1 setEntity2:entity2] It ends with:
2014-06-22 08:48:24.444 MultiContextualCoreData[1324:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'entity1' between objects in different contexts (source = <Entity2: 0x8c81570> (entity: Entity2; id: 0x8c80000 <x-coredata:///Entity2/tC31696AE-0A0A-424E-9C8E-1E19085F3FB43> ; data: {
entity1 = nil;
}) , destination = <Entity1: 0x8c80200> (entity: Entity1; id: 0x8c80250 <x-coredata:///Entity1/tC31696AE-0A0A-424E-9C8E-1E19085F3FB42> ; data: {
arg1 = ABC;
arg2 = DEF;
entity2 = nil;
}))'
*** First throw call stack:
(
0 CoreFoundation 0x01b541e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018d38e5 objc_exception_throw + 44
2 CoreData 0x00293b7e _PFManagedObject_coerceValueForKeyWithDescription + 3614
3 CoreData 0x002614e9 _sharedIMPL_setvfk_core + 185
4 CoreData 0x0027ada7 _svfk_0 + 39
5 MultiContextualCoreData 0x00002d4a -[AppDelegate test] + 554
6 MultiContextualCoreData 0x00002acd -[AppDelegate application:didFinishLaunchingWithOptions:] + 605
7 UIKit 0x0058d14f -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 309
8 UIKit 0x0058daa1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1810
9 UIKit 0x00592667 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
10 UIKit 0x005a6f92 -[UIApplication handleEvent:withNewEvent:] + 3517
11 UIKit 0x005a7555 -[UIApplication sendEvent:] + 85
12 UIKit 0x00594250 _UIApplicationHandleEvent + 683
13 GraphicsServices 0x03a07f02 _PurpleEventCallback + 776
14 GraphicsServices 0x03a07a0d PurpleEventCallback + 46
15 CoreFoundation 0x01acfca5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
16 CoreFoundation 0x01acf9db __CFRunLoopDoSource1 + 523
17 CoreFoundation 0x01afa68c __CFRunLoopRun + 2156
18 CoreFoundation 0x01af99d3 CFRunLoopRunSpecific + 467
19 CoreFoundation 0x01af97eb CFRunLoopRunInMode + 123
20 UIKit 0x00591d9c -[UIApplication _run] + 840
21 UIKit 0x00593f9b UIApplicationMain + 1225
22 MultiContextualCoreData 0x00002efd main + 141
23 libdyld.dylib 0x0219b701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
What i did wrong here?
Thank you for help in advance.
The issue is that two objects have to belong to the same context in order to establish relationships between them. In your case, one of the contexts has a private type, it has its own queue to work at, where the main context works on the main queue. This is a way to protect you from running into concurrency problems down the road.
Possible solution are
Create the entity1, save the main context, retrieve it in the child context using managedObjectID or a fetch request if it makes more sense and only then establish relationship when you have entity1 and entity2 in the same context
Or, simply, create both objects in the same context, if your logic allows it.
I have a nasty bug and I would appreciate any guidance pointing me in the general direction of a solution. Occasionally, I get the following exception which pertains to calling initWithCoder on 3 different NSManagedObject subclasses in my core data model. If I delete the app from my device and reload it, or reset content on the simulator the exception goes away. No where in my code do I explicitly call initWithCoder on an NSManagedObject Subclass.
The bug seems to arise randomly after editing random parts of my source code. Any ideas on where to begin?
2014-01-11 15:59:22.078 Flip Evaluator and Manager[354:a0b] -[SellingCosts initWithCoder:]: unrecognized selector sent to instance 0xc2cec80
2014-01-11 15:59:22.079 Flip Evaluator and Manager[354:a0b] CoreData: error: exception during fetchRowForObjectID: -[SellingCosts initWithCoder:]: unrecognized selector sent to instance 0xc2cec80 with userInfo of (null)
2014-01-11 15:59:22.081 Flip Evaluator and Manager[354:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SellingCosts initWithCoder:]: unrecognized selector sent to instance 0xc2cec80'
*** First throw call stack:
(
0 CoreFoundation 0x01e9a5e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01c1d8b6 objc_exception_throw + 44
2 CoreFoundation 0x01f37903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x01e8a90b ___forwarding___ + 1019
4 CoreFoundation 0x01e8a4ee _CF_forwarding_prep_0 + 14
5 Foundation 0x01830b2a _decodeObjectBinary + 3498
6 Foundation 0x0182fc15 _decodeObject + 340
7 Foundation 0x0182fab9 -[NSKeyedUnarchiver decodeObjectForKey:] + 181
8 Foundation 0x018a168d +[NSKeyedUnarchiver unarchiveObjectWithData:] + 106
9 Foundation 0x018202e5 -[_NSKeyedUnarchiveFromDataTransformer transformedValue:] + 47
10 CoreData 0x0064bd09 _prepareResultsFromResultSet + 4105
11 CoreData 0x00649583 newFetchedRowsForFetchPlan_MT + 1795
12 CoreData 0x0063448e -[NSSQLCore newRowsForFetchPlan:] + 526
13 CoreData 0x0065302e -[NSSQLCore fetchRowForObjectID:] + 1198
14 CoreData 0x00650798 -[NSSQLCore newValuesForObjectWithID:withContext:error:] + 296
15 CoreData 0x00650667 -[NSPersistentStoreCoordinator(_NSInternalMethods) newValuesForObjectWithID:withContext:error:] + 71
16 CoreData 0x0064fa3b _PFFaultHandlerLookupRow + 411
17 CoreData 0x0064f897 -[NSFaultHandler fulfillFault:withContext:forIndex:] + 39
18 CoreData 0x0064f473 _PF_FulfillDeferredFault + 259
19 CoreData 0x0064f2c6 _sharedIMPL_pvfk_core + 70
20 CoreData 0x00653cd5 -[NSManagedObject(_PFDynamicAccessorsAndPropertySupport) _genericValueForKey:withIndex:flags:] + 85
21 CoreData 0x0068d781 _PF_Handler_Public_GetProperty + 161
22 CoreData 0x0068d685 -[NSManagedObject valueForKey:] + 149
23 Flip Evaluator and Manager 0x00030c4c -[OzCalculator sumTheValuesInSet:withAttributeKeyForValue:] + 428
24 Flip Evaluator and Manager 0x0002f7d5 -[OzCalculator sumMoreCostsAndUpdateDataModelFor:] + 165
25 Flip Evaluator and Manager 0x0002edc1 -[OzCalculator performAllCalculationsOnProperty:] + 817
26 Flip Evaluator and Manager 0x00002d37 -[OzPropertyConverter createAManagedPropertyFromAnEvaluatedProperty:] + 1175
27 Flip Evaluator and Manager 0x00041233 -[OzHaveYouPurchasedThisProperty goForwardToNextView] + 307
28 libobjc.A.dylib 0x01c2f874 -[NSObject performSelector:withObject:withObject:] + 77
29 UIKit 0x0098d0c2 -[UIApplication sendAction:to:from:forEvent:] + 108
30 UIKit 0x0098d04e -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
31 UIKit 0x00a850c1 -[UIControl sendAction:to:forEvent:] + 66
32 UIKit 0x00a85484 -[UIControl _sendActionsForEvents:withEvent:] + 577
33 UIKit 0x00a841fd -[UIControl touchesBegan:withEvent:] + 254
34 UIKit 0x009ca34b -[UIWindow _sendTouchesForEvent:] + 386
35 UIKit 0x009cb184 -[UIWindow sendEvent:] + 1232
36 UIKit 0x0099ee86 -[UIApplication sendEvent:] + 242
37 UIKit 0x0098918f _UIApplicationHandleEventQueue + 11421
38 CoreFoundation 0x01e2383f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
39 CoreFoundation 0x01e231cb __CFRunLoopDoSources0 + 235
40 CoreFoundation 0x01e4029e __CFRunLoopRun + 910
41 CoreFoundation 0x01e3fac3 CFRunLoopRunSpecific + 467
42 CoreFoundation 0x01e3f8db CFRunLoopRunInMode + 123
43 GraphicsServices 0x02c2a9e2 GSEventRunModal + 192
44 GraphicsServices 0x02c2a809 GSEventRun + 104
45 UIKit 0x0098bd3b UIApplicationMain + 1225
46 Flip Evaluator and Manager 0x0002e5dd main + 141
47 libdyld.dylib 0x030c1725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Code:
//
// SellingCosts.h
// Flip Evaluator and Manager
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class Cost, Property, TotalCosts;
#interface SellingCosts : NSManagedObject
#property (nonatomic, strong) NSNumber * deedPrep;
#property (nonatomic, strong) NSNumber * realtyCommisionAmount;
#property (nonatomic, strong) NSNumber * realtyCommisionPercent;
#property (nonatomic, strong) NSNumber * totalCost;
#property (nonatomic, strong) NSSet *moreCosts;
#property (nonatomic, strong) Property *property;
#property (nonatomic, strong) TotalCosts *totalCosts;
#property (nonatomic, strong) NSNumber * transferTaxAmount;
#property (nonatomic, strong) NSNumber * transferTaxPercent;
#property (nonatomic, strong) NSNumber *totalIncompleteCost;
#property (nonatomic, strong) NSNumber *totalCompleteCost;
#end
Here is the method that is called before things go wrong:
-(NSInteger)sumTheValuesInSet:(NSMutableSet *)set withAttributeKeyForValue:(NSString *)attributeKey
{
NSInteger sumToReturn = 0;
for (id obj in set) {
sumToReturn = sumToReturn +[[obj valueForKey:attributeKey] integerValue];
}
return sumToReturn;
}
The method enumerates through Cost objects in the NSSet [sellingCosts valueForKey:#"moreCosts"].
Here is the model for the Cost object//
// Cost.h
// Flip Evaluator and Manager
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class BuyingCosts, HoldingCosts, SellingCosts, OtherCosts, TotalCosts;
#interface Cost : NSManagedObject
#property (nonatomic, strong) BuyingCosts *buyingCosts;
#property (nonatomic, strong) HoldingCosts *holdingCosts;
#property (nonatomic, strong) SellingCosts *sellingCosts;
#property (nonatomic, strong) OtherCosts *otherCosts;
#property (nonatomic, strong) NSString * name;
#property (nonatomic, strong) TotalCosts *incompleteCosts;
#property (nonatomic, strong) TotalCosts *completedCosts;
#property (nonatomic, strong) NSNumber *complete;
#property (nonatomic, strong) id costType;
#property (nonatomic, strong) NSNumber *amount;
#end
Share your model as well as this appears to be a transform problem at first glance.
You should also share the code in -sumTheValuesInSet:withAttributeKeyForValue: as that seems to be the last point in your code before things go wrong.
I know similar questions have been asked but they all have different answers and none seem to help me.
So, I've got an app called TherapistScheduler, which has therapistScheduler.xcdatamodel in a /Data folder at the root of the project. Inside that folder is a Session.h and Session.m file, which match up with my Session entity in my data model.
My app delegate has the functions managedObjectContext, managedObjectModel, and persistantStoreCoodinator in it.
Inside my applicationDidFinishLaunching method, I've added a view controller (loginViewController) over the top of my rootViewController (which is a tabBarController), and I'm trying to access my Session entity from there.
I'm using the following code to try and save a value - this is throwing the error:
// create session
Session *session = (Session *) [NSEntityDescription insertNewObjectForEntityForName:#"Session" inManagedObjectContext:self.managedObjectContext];
[session setSessionHash:strUserhash];
The loginViewController.h file contains:
NSManagedObjectContext *managedObjectContext; // in the interface declaration
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; // after the interface
The loginViewController.m file contains
#synthesize managedObjectContext;
Do I need to do something in the loginViewController viewDidLoad to initialise the managedObjectContext? I'm a bit lost as to how this all works. I want to be able to access the data stored in the managedObjectContext from any view I switch to on the tab bar.
I know I'll probably need to add more code to the question, but I don't know what else is needed.
The error I'm getting is this:
TherapistScheduler[40752:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Session''
*** Call stack at first throw:
(
0 CoreFoundation 0x02581919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0295b5de objc_exception_throw + 47
2 CoreData 0x0004525b +[NSEntityDescription entityForName:inManagedObjectContext:] + 187
3 CoreData 0x0007cd8b +[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] + 59
4 TherapistScheduler 0x000030ce -[LoginViewController processLoginForUserhash:andType:] + 142
5 TherapistScheduler 0x000039fa -[LoginViewController connectionDidFinishLoading:] + 330
6 Foundation 0x01f91666 -[NSURLConnection(NSURLConnectionReallyInternal) sendDidFinishLoading] + 108
7 Foundation 0x01f915bf _NSURLConnectionDidFinishLoading + 133
8 CFNetwork 0x02b8d9f1 _ZN19URLConnectionClient23_clientDidFinishLoadingEPNS_26ClientConnectionEventQueueE + 285
9 CFNetwork 0x02c56c72 _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 402
10 CFNetwork 0x02c570ea _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 1546
11 CFNetwork 0x02c570ea _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 1546
12 CFNetwork 0x02b82dfe _ZN19URLConnectionClient13processEventsEv + 100
13 CFNetwork 0x02b82c95 _ZN17MultiplexerSource7performEv + 247
14 CoreFoundation 0x02562d7f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
15 CoreFoundation 0x024c11dd __CFRunLoopDoSources0 + 333
16 CoreFoundation 0x024c07c6 __CFRunLoopRun + 470
17 CoreFoundation 0x024c0280 CFRunLoopRunSpecific + 208
18 CoreFoundation 0x024c01a1 CFRunLoopRunInMode + 97
19 GraphicsServices 0x02de62c8 GSEventRunModal + 217
20 GraphicsServices 0x02de638d GSEventRun + 115
21 UIKit 0x00215b58 UIApplicationMain + 1160
22 TherapistScheduler 0x00001f3d main + 125
23 TherapistScheduler 0x00001eb5 start + 53
24 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
I had to refer to the managedObjectContext as a property of the app delegate not self. So it looked like appDelegate.managedObjectContext.
When you passed the managedObjectContext, I think what you did is like this:
TimelineTableViewController * timelineTableViewController;
timelineTableViewController = [TimelineTableViewController alloc];
[timelineTableViewController initWithStyle:UITableViewStylePlain];
timelineTableViewController.managedObjectContext = self.managedObjectContext;
//...
and then in TimelineTableViewController's viewDidLoad: method, you wanted to fetch the data by managedObjectContext, huh?
I debugged this issue and found that TimelineTableViewController's viewDidLoad: will be dispatched quicker than timelineTableViewController.managedObjectContext = self.managedObjectContext; (where you passed the managedObjectContext from parent (or the AppDelegate) to child). So when you were trying to fetch the data, the managedObjectContext is nil actually. That's why you got this issue:
'+entityForName: could not locate an NSManagedObjectModel for entity name 'Session''
WORKAROUND:
What you have to do is to make sure that the managedObjectContext is not nil when you need to fetch the data:
TimelineTableViewController * timelineTableViewController;
timelineTableViewController = [TimelineTableViewController alloc];
timelineTableViewController.managedObjectContext = self.managedObjectContext;
[timelineTableViewController initWithStyle:UITableViewStylePlain];
// ...
I just solved this issue by this way (no need to use AppDelegate's managedObjectContext directly).