Restkit mapping issue - post newly created managed object to the server - core-data

I'm trying to post new managed object to the server by using rest kit, but I don't know what I'm doing wrong. I'm getting exception like the following:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'RKRequestDescriptor objects must be initialized with a mapping whose target class is NSMutableDictionary, got 'Users' (see [RKObjectMapping requestMapping])'
I was looking for solution in stack overflow posts like this one
This is my entity mapping method from MappingProvider class:
+(RKMapping *)usersMapping
{
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:#"Users" inManagedObjectStore:[[DateModel sharedDataModel]objectStore]];
[mapping addAttributeMappingsFromDictionary:#{
#"id": #"user_id",
#"address1": #"address1",
#"address2": #"address2",
#"created_at":#"created_at",
#"updated_at": #"updated_at",
#"email": #"email",
#"name":#"name",
#"password_digest": #"password_digest",
#"phone_no": #"phone_no",
#"postcode":#"postcode",
#"remember_token":#"remember_token",
#"user_type": #"user_type",
#"apns_token":#"apns_token"
}
];
[mapping addRelationshipMappingWithSourceKeyPath:#"admins" mapping:[MappingProvider adminsMapping]];
[mapping addRelationshipMappingWithSourceKeyPath:#"carers" mapping:[MappingProvider carersMapping]];
[mapping addRelationshipMappingWithSourceKeyPath:#"customers" mapping:[MappingProvider customersMapping]];
[mapping addRelationshipMappingWithSourceKeyPath:#"userWearers" mapping:[MappingProvider customersMapping]];
return mapping;
This is the method called when user fill all the textfields and click the register button:
-(void)registerUser
{RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[MappingProvider usersMapping] method:RKRequestMethodPOST pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
//here Xcode return exception
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[MappingProvider usersMapping] objectClass:[Users class] rootKeyPath:nil method:RKRequestMethodPOST];
[[DateModel sharedDataModel]addResponseDescriptor:userResponseDescriptor];
[[DateModel sharedDataModel]addRequestDescriptor:requestDescriptor];
RKManagedObjectStore *objectStore = [[DateModel sharedDataModel]objectStore];
Users *user = [NSEntityDescription insertNewObjectForEntityForName:#"Users" inManagedObjectContext:objectStore.mainQueueManagedObjectContext];
user.email = _email;
user.password_digest =_password;
user.name = _name;
user.address1 = _address;
user.postcode = [NSNumber numberWithInteger:[_postcode integerValue]];
user.phone_no = [NSNumber numberWithInteger:[_mobileNumber integerValue]];
[[RKObjectManager sharedManager] postObject:user path:nil parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success saving user");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failure saving user: %#", error.localizedDescription);
}];
}
Date-model setup method:
- (void)setup {
self.objectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:#"Data.sqlite"];
NSLog(#"Setting up store at %#", path);
[self.objectStore addSQLitePersistentStoreAtPath:path
fromSeedDatabaseAtPath:nil
withConfiguration:nil
options:[self optionsForSqliteStore]
error:nil];
[self.objectStore createManagedObjectContexts];
//Configure a managed object cache to ensure we do not create duplicate objects
self.objectStore.managedObjectCache =[[RKInMemoryManagedObjectCache alloc]initWithManagedObjectContext:self.objectStore.persistentStoreManagedObjectContext];
// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:self.objectStore];
}

The purpose of the request descriptor is to convert your custom object into an NSMutableDictionary so that it can be serialised and sent. The mapping you're currently using is for converting into a Users object, so you need to use a different mapping.
RestKit has a convenience method that you can use:
... requestDescriptorWithMapping:[[MappingProvider usersMapping] inverseMapping] ...

Related

FetchRequest does not return NSManagedObjects fetched via RestKit 0.2

I am having the following problem: I use RestKit to get objects form a REST Api. The object mapping works, which I can see from the RK Debugger Output. However, when I perform a fetch request afterwards, the result is empty. I am talking about NSManagedObjects. I have the following setup.
1: Restkit and Coredata stack initialization:
NSError *error;
NSURL *baseURL = [NSURL URLWithString:#"https://mfihost.us/gocoffee/api/V1/"];
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];
[objectManager.HTTPClient setDefaultHeader:#"Token" value:[NSString stringWithFormat:#"%#",[FBSDKAccessToken currentAccessToken].tokenString]];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;
//[RKObjectManager setSharedManager:objectManager];
[FetchRequests registerFetchRequests:objectManager];
[Descriptors registerDescriptors:objectManager];
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore *persistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(persistentStore, #"Failed to add inmemory store with error: %#", error);
[managedObjectStore createManagedObjectContexts];
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
2: call to get objects from server and performing a fetch request afterwards:
[[RKObjectManager sharedManager]
postObject:nil path:#"/gocoffee/api/V1/login/IOS"
parameters:nil
success: ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Objects have been saved in core data.");
NSManagedObjectContext *managedObjCtx = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
// Shout* sh=[managedObjCtx insertNewObjectForEntityForName:#"Shout"];
// sh.inviterUserId=#"22223";
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Shout" inManagedObjectContext:managedObjCtx];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *result = [managedObjCtx executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(#"Unable to execute fetch request.");
NSLog(#"%#, %#", error, error.localizedDescription);
} else {
NSLog(#"%#", result);
}
completionBlock();
}
failure: ^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(#"Load failed with error: %#", error);
}];
The fetch result is empty, although the server returns objects and these objects are properly mapped by using RKEntityMappings and the corresponding response descriptors. Confusingly, if I uncomment the two lines //Shout * .... (i.e. manually insert a managed oject into the context), then this object is fetched by the fetch request. Consequently, the fetch request should be working fine.
I am searching for ages now what the problem might be. Could it be that I am calling on the wrong context or something ? By the way: core-data multi-threading debugging is enabled and does not show any error, i.e. no "AllThatIsLeftToUsIsHonor" error.
The corresponding route from the above example is:
[objectManager.router.routeSet
addRoute:[RKRoute routeWithName:#"loginAndOrSignup"
pathPattern:#"login/IOS"
method:RKRequestMethodPOST]
];
The descriptors look like (example):
[objectManager addResponseDescriptor:
[RKResponseDescriptor responseDescriptorWithMapping:[shoutMapping inverseMapping]
method:RKRequestMethodPOST
pathPattern: #"login/IOS"
keyPath:#"response.incomingshoutapplications"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
]
];
Shout mapping is as follows:
RKEntityMapping *shoutMapping = [RKEntityMapping mappingForEntityForName:#"Shout" inManagedObjectStore:managedObjectStore];
shoutMapping.identificationAttributes = #[ #"id" ];
[shoutMapping addAttributeMappingsFromDictionary:#{
#"id" : #"id",
#"inviterUserId" : #"inviterUserId",
#"eventType" : #"eventType",
#"eventTime" : #"eventTime",
#"locationLat" : #"locationLat",
#"locationLng" : #"locationLng",
#"radius" : #"radius",
#"targetGender" : #"targetGender",
#"state" : #"state",
#"buddyOnly" : #"buddyOnly",
#"timeCreated" : #"timeCreated"
}
];
The "manager" ist the one from above, the managedObjectStore is manager.managedObjectStore
All the mappings and descriptors are setup in another method that is calles by [Descriptors registerDescriptors:objectManager]; (see first block of code)
The problem is probably that you're using inverseMapping. That is used mainly for request mapping, because it's a mapping that creates instances of NSMutableDictionary, which isn't what you want.
So, what I expect is happening is that the response is mapped successfully, but to plain objects, not managed objects, and then you're throwing the result away.
Just change to
... responseDescriptorWithMapping:shoutMapping ...

Migrate core data to add new attribute

I have added new attribute and I need to migrate core data. As a result, I do like this.
Bus.xcDataModel >> Add model version
Then, I add new attribute. I change persistent store coordinator option as well like this.
#{NSMigratePersistentStoresAutomaticallyOption:#YES, NSInferMappingModelAutomaticallyOption:#YES}
But when I add that new attribute, it show me like this. How shall I do?
-[BusService setBus_wap:]: unrecognized selector sent to instance 0x1742a7320
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator_busservice
{
if (_persistentStoreCoordinator_busservice != nil)
return _persistentStoreCoordinator_busservice;
NSURL *applicationDocumentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [applicationDocumentsDirectory URLByAppendingPathComponent:#"Busservice_new.sqlite"];
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]] &&
!self.preloadEnabled)
{
NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Busservice_new" ofType:#"sqlite"]];
NSError* err = nil;
if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err])
DLog(#"Oops, could not copy preloaded data");
}
NSError *error = nil;
_persistentStoreCoordinator_busservice = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator_busservice addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:#{NSMigratePersistentStoresAutomaticallyOption:#YES, NSInferMappingModelAutomaticallyOption:#YES} error:&error])
{
DLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator_busservice;
}
From that error it looks like you added a new attribute to your BusService entity in Core Data, but did not add the attribute to your BusService class. If you want to use accessor methods for this new attribute, you need to update the class as well. Or you can leave the class alone but use setValue:forKey: to assign values to the new attribute.

Loading Core Data relationships from existing database ID relationships

I have an application that has lots of data in tables, and I'm writing a mobile app that gets a small portion of the data. The data in tables uses IDs for relations, and I'm trying to load it into a Core Data model and preserve the relationships.
But it doesn't seem like there's an easy way to tell Core Data, "For this relationship, I want a foreign key to this other table." Instead, I have this monstrosity (this is a simplified version of only one of six asynchronous RestKit queries that are coming back to fill the database):
[manager postObject:nil path:#"api/shiftservice/get" parameters:#{#"workerIds": #[#1]} success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Loaded shifts: %d", [[mappingResult array] count]);
NSManagedObjectContext *context = [AppDelegate managedObjectContext];
NSSet *positions = [context fetchObjectsForEntityName:#"NWPosition"];
NSDictionary *positionDict = [NSMutableDictionary new];
for (NWPosition *position in positions) [positionDict setValue:position forKey:position.positionId.stringValue];
NSSet *workers = [context fetchObjectsForEntityName:#"NWWorker"];
NSDictionary *workerDict = [NSMutableDictionary new];
for (NWWorker *worker in workers) [workerDict setValue:worker forKey:worker.workerId.stringValue];
NSSet *shifts = [context fetchObjectsForEntityName:#"NWShift"];
for (NWShift *shift in shifts)
{
NWPosition *position = [positionDict valueForKey:shift.positionId.stringValue];
position.shifts = [context fetchObjectsForEntityName:#"NWShift" withPredicateFormat:#"positionId = %d", position.positionId];
shift.position = position;
NSSet *tradesAsGetShift = [context fetchObjectsForEntityName:#"NWTrade" withPredicateFormat:#"getShiftId = %#", shift.shiftId];
for (NWTrade *trade in tradesAsGetShift) trade.getShift = shift;
shift.tradesAsGetShift = tradesAsGetShift;
NSSet *tradesAsGiveShift = [context fetchObjectsForEntityName:#"NWTrade" withPredicateFormat:#"giveShiftId = %#", shift.shiftId];
for (NWTrade *trade in tradesAsGiveShift) trade.giveShift = shift;
shift.tradesAsGiveShift = tradesAsGiveShift;
NWWorker *worker = [workerDict valueForKey:shift.workerId.stringValue];
worker.shifts = [context fetchObjectsForEntityName:#"NWShift" withPredicateFormat:#"workerId = %d", worker.workerId];
shift.worker = worker;
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failed to load shifts with error: %#", [error localizedDescription]);
}];
I'm using a modified version of Matt Gallagher's One-Line Fetch at http://www.cocoawithlove.com/2008/03/core-data-one-line-fetch.html for the fetchObjectsForEntityName.
Anyway, this seems pretty horrible to me, like I'm missing something obvious. Is there some way to just tell Core Data about database-style foreign keys? Is there an easy way to populate them, if there isn't? Because doing this many fetches for every single entity sure doesn't seem like the right way to do it. And if RestKit helps out here, so much the better.
Nope, but there should be no need to set the inverse relationships.
Thanks to Wain and his insightful comment, I managed to get RestKit to do this for me in a reasonably-elegant fashion. Here is how I set up the foreign key relationships. I set up both ends of each relationship so that either set of data could come in first and the relationship would still get populated properly.
First, I set up the manager, telling it to use JSON serialization:
RKManagedObjectStore *store = [AppDelegate managedObjectStore];
RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:oauthClient];
[RKObjectManager setSharedManager:manager];
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:RKMIMETypeJSON];
[manager.HTTPClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[manager registerRequestOperationClass:[AFJSONRequestOperation class]];
[manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
[manager setRequestSerializationMIMEType:RKMIMETypeJSON];
manager.managedObjectStore = store;
Next, I set up connections and response descriptors:
NSManagedObjectContext *context = [AppDelegate managedObjectContext];
NSDictionary *orgRels = [[NSEntityDescription entityForName:#"NWOrg" inManagedObjectContext:context] relationshipsByName];
NSDictionary *positionRels = [[NSEntityDescription entityForName:#"NWPosition" inManagedObjectContext:context] relationshipsByName];
// ...
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
NSArray *orgConnections =
#[[self connectionForRelation:#"positions" localKey:#"orgId" foreignKey:#"orgId" withRels:orgRels],
[self connectionForRelation:#"workers" localKey:#"orgId" foreignKey:#"orgId" withRels:orgRels]];
[manager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:
[self entityMappingForName:#"NWOrg" fromDictionary:#{#"orgId": #"orgId", #"orgName": #"orgName"} withKey:#"orgId" andConnections:orgConnections]
method:RKRequestMethodAny pathPattern:#"api/orgservice/get" keyPath:nil statusCodes:statusCodes]];
NSArray *positionConnections =
#[[self connectionForRelation:#"org" localKey:#"orgId" foreignKey:#"orgId" withRels:positionRels],
[self connectionForRelation:#"shifts" localKey:#"positionId" foreignKey:#"positionId" withRels:positionRels]];
[manager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:
[self entityMappingForName:#"NWPosition" fromDictionary:#{#"positionId": #"positionId", #"orgId": #"orgId", #"name": #"positionName"} withKey:#"positionId" andConnections:positionConnections]
method:RKRequestMethodAny pathPattern:#"api/positionservice/get" keyPath:nil statusCodes:statusCodes]];
// ...
Then, I was able to do the simple request, and it worked great:
[manager postObject:nil path:#"api/shiftservice/get" parameters:#{#"workerIds": #[#1]}
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Loaded shifts: %d", [[mappingResult array] count]);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failed to load shifts with error: %#", [error localizedDescription]);
}];
Note: This used a few helper methods, which I will reproduce here:
- (RKConnectionDescription *)connectionForRelation:(NSString *)relation
localKey:(NSString *)localKey foreignKey:(NSString *)foreignKey
withRels:(NSDictionary *)rels
{
return [[RKConnectionDescription alloc] initWithRelationship:rels[relation]
attributes:#{localKey: foreignKey}];
}
- (RKEntityMapping *)entityMappingForName:(NSString *)name
fromDictionary:(NSDictionary *)dict withKey:(NSString *)key
{
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:name
inManagedObjectStore:[AppDelegate managedObjectStore]];
[mapping addAttributeMappingsFromDictionary:dict];
mapping.assignsDefaultValueForMissingAttributes = YES;
mapping.assignsNilForMissingRelationships = YES;
mapping.identificationAttributes = #[key];
return mapping;
}
- (RKEntityMapping *)entityMappingForName:(NSString *)name
fromDictionary:(NSDictionary *)dict withKey:(NSString *)key
andConnections:(NSArray *)connections
{
RKEntityMapping *mapping = [self entityMappingForName:name
fromDictionary:dict withKey:key];
for (RKConnectionDescription *connection in connections)
{
[mapping addConnection:connection];
}
return mapping;
}

Restkit truncate db before core data mapping

i'm using restkit to map a json with core data
i need to call a routine every time the user launch the app.
if the server has updated data to send, i need to download them, truncate my table and insert the data in the table, if the server sends me nothing i don't have to do nothing.
obviously i want to truncate my current data only when i'm sure that new data has been downloaded, not before
how can I achieve this?
this is my code:
NSURL *endpoint = [NSURL URLWithString:kBaseURL];
RKObjectManager* objectManager = [RKObjectManager managerWithBaseURL:endpoint];
[objectManager.HTTPClient setAuthorizationHeaderWithToken:#"username:my-token-12345"];
objectManager.managedObjectStore = [RKManagedObjectStore defaultStore];
[RKObjectManager setSharedManager:objectManager];
RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:#"Medic" inManagedObjectStore:objectManager.managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:#{
#"identifier": #"identifier",
#"name": #"name",
#"surname": #"surname",
#"personalAddress": #"personalAddress",
#"hospital": #"hospital",
#"hospitalAddress": #"hospitalAddress",
#"oldDigitalAgreement": #"oldDigitalAgreement",
#"oldPaperAgreement": #"oldPaperAgreement"}];
entityMapping.identificationAttributes = #[#"identifier"];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor
responseDescriptorWithMapping:entityMapping
method:RKRequestMethodAny
pathPattern:nil
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
[[RKObjectManager sharedManager] getObjectsAtPath:kregistryURL
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
// done
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:NSLocalizedString(#"attention", nil) message:NSLocalizedString(#"communication.genericerror.title", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alertView show];
}
];
solution after Wain answer
[objectManager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) {
RKPathMatcher* pathMatcher = [RKPathMatcher pathMatcherWithPattern:kregistryURL];
NSDictionary *dic = nil;
if ([pathMatcher matchesPath:[URL relativePath] tokenizeQueryStrings:YES parsedArguments:&dic]) {
NSFetchRequest *fetchRequest = [NSFetchRequest new];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Medic"
inManagedObjectContext: [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext];
fetchRequest.entity = entity;
return fetchRequest;
} else
return nil;
}];
Your problem is
if the server sends me nothing, i don't have to do _any_thing
and I'm guessing the server still sends a 200 response rather than a special status code (it should be 304 ‘Not Modified’). Because if you didn't have that requirement you could use a deletion fetch request block (which is the correct solution).
As it stands, you will likely have to do the deletion yourself by fetching the existing items from the data store and iterating over them, checking if the item is in the mapping results provided to you in the success block and, if not, deleting it from the context...

Strange Core Data Error During Migration

I'm absolutely pulling my hair out with Core Data after yet another bizarre error that I can't seem to solve.
This will be the fourth version of the Data model, the previous migrations have worked (albeit with some headaches).
All I'm trying to do is add a property of String type to an 'Engines' entity. I create a new version of the model (version 4) based on the current version (v3). I select the newly created version 4 as the 'Current model' and add the string property to the Engines entity. I then create a new mapping model, using v3 as the source and v4 as the target. I delete the previous Engines NSManagedObject subclass, and create a new one using the new, modified Engines entity, checking to make sure that the new String property is in the header file. I clean build the app and run it, and boom! I get this error, about 18 times:
{NSDetailedErrors=(
"Error Domain=NSCocoaErrorDomain Code=1570 \"The operation couldn\U2019t be completed. (Cocoa error 1570.)\" UserInfo=0x6015820 {NSValidationErrorObject= (entity: BodySet; id: 0x60ba670 ; data: ), NSValidationErrorKey=availableCar, NSLocalizedDescription=The operation couldn\U2019t be completed. (Cocoa error 1570.)}",
BodySet is another entity in the model, but I haven't touched it during this migration, so why is it causing all these errors?
I'm not sure if this is a help or not, but here's my Core Data code:
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
NSString *path = [[NSBundle mainBundle] pathForResource:#"CoreDataTest" ofType:#"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
return managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
stringByAppendingPathComponent:#"<Project Name>.sqlite"]];
//get the DB from the Documents directory:
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
stringByAppendingPathComponent: #"<Project Name>.sqlite"]];
NSLog(#"Loading DB at path: %#", [storeUrl path]);
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeUrl options:options error:&error]) {
/*Error for store creation should be handled in here*/
NSLog(#"Something went wrong....%#", [error description]);
}
return persistentStoreCoordinator;
}
Any help with this is very much appreciated.
i have fixed it ,maybe you can change "availableCar“ item to optional

Resources