I am trying to create a CoreData store with iCloud. Following the example code in iCloud Programming Guide for Core Data, I have this piece of code:
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: salonbook.xcdatamodeld];
This is the image of my managed object model
I'm getting an error: Use of undeclared identifier 'salonbook'.
Why?
You're getting the error because you're telling it to look for a variable named salonbook, which is not declared. You need to pass a reference to an NSManagedObjectModel instance here. Commonly that means you'd use self.managedObjectModel, but that really depends on the rest of your code. The steps need to be:
Create an NSManagedObjectModel instance from the model file
Create an NSPersistentStoreCoordinator using that model object.
Related
I have an existing (and fully working) app using NSPersistentDocument to save the application files.
Now I need to create a new entity, this new entity is totally unrelated to the application files and it will contain the application cache, so I will use it to save on a separated file.
My project contains the MyDocument.xcdatamodeld used by NSPersistentDocument, to implement the new feature I created a new data model Cache.xcdatamodeld and added a new entity to the model (I have not written code just used XCode wizards) but when I run the app and try to open an existing app file I receive the error
The model used to open the store is incompatible with the one used to
create the store
I understand this occurs because the model configuration for new entity is the same for NSPersistentDocument but how can I decouple it?
Creating a new configuration in data model doesn't work because the entity can't be deleted from the default one.
Any idea how to make NSPersistentDocument ignore the new entity and continue to work with the old data model?
I don't post source code because this happens simply adding the new model and entity to project
From the documentation of NSPersistDocument's managedObjectModel property:
#property(readonly, strong) NSManagedObjectModel *managedObjectModel
Discussion
By default the Core Data framework creates a merged model from all models in the application bundle ([NSBundle mainBundle]). You can reimplement this property and return a specific model to use to create persistent stores. A typical implementation might include code similar to the following fragment:
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:#"MyModel" ofType:#"mom"];
NSURL *url = [NSURL fileURLWithPath:path];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
How can I create a custom managed object, but without to save, just keep it in the memory and when app stops, temporary managed object can be dealloched too. But same time other managed objects I need to save.
There are a couple of possibilities depending on how your app works.
One is to just create the object and just not insert it. It's just that simple. Pass a nil value for the context.
NSManagedObjectModel *managedObjectModel =
[[self.managedObjectContext persistentStoreCoordinator] managedObjectModel];
NSEntityDescription *entity = [[managedObjectModel entitiesByName] objectForKey:#"EntityName"];
NSManagedObject *myObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
If you later want to insert the object, use [NSManagedObjectContext insertObject:].
Another is to create an in-memory Core Data store. Create a second persistent store, but replace NSSQLiteStoreType with NSInMemoryStoreType. Then create and use objects as usual. When the app exits, the in-memory store will just disappear with all of its objects.
I am migrating my connection classes to support Caching via CoreData. RestKit does it automagically using RKEntityMapping. RestKit and CoreData did the mapping and validation correctly, I got a bunch of NSManagedObject I requested for but it is not saving the objects to the CoreData. When I check the logs, I got this.
W restkit.network.core_data:RKManagedObjectRequestOperation.m:776 Saving of managed object context failed, but a `nil` value for the `error` argument was returned. This typically indicates an invalid implementation of a key-value validation method exists within your model. This violation of the API contract may result in the save operation being mis-interpretted by callers that rely on the availability of the error.
E restkit.network.core_data:RKManagedObjectRequestOperation.m:818 Failed saving managed object context to the persistent store <NSManagedObjectContext: 0x145e5ce0>: (null)
I don't have an idea, why is this occurring. I checked my Model for wrong settings or attributes but I can't find any. As I observed, NSManagedObjects is saved InMemory (NSFetchResultsController was still able to fetch the objects even when I leave the view. So I guess, the objects were saved InMemory). Can someone help me find what is wrong here. Leaving any tips for debugging the problem is welcome. Thank you.
I had this code to setup the core data.
- (void)setupCoreData
{
NSManagedObjectModel *managedObjectModel = [[AppDelegate sharedDelegate] managedObjectModel];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
[[RKObjectManager sharedManager] setManagedObjectStore:managedObjectStore];
[managedObjectStore createPersistentStoreCoordinator];
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:#"Model.sqlite"];
NSError *error;
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:nil withConfiguration:nil options:#{NSMigratePersistentStoresAutomaticallyOption:#YES, NSInferMappingModelAutomaticallyOption:#YES} error:&error];
NSAssert(persistentStore, #"Failed to add persistent store with error: %#", error);
// Create the managed object contexts
[managedObjectStore createManagedObjectContexts];
// Configure a managed object cache to ensure we do not create duplicate objects
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
}
This is called before I add all response/request descriptors. I generated the model class using MoGenerator. I override some setters and did some validations before inserting (validateForInsert).
Dear community.
I try to discover opportunity to using 2 persistent stores for improve performance of my application.
What i do here:
CREATE 2 PERSISTENT STORES
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNumber numberWithBool:YES]
forKey:NSMigratePersistentStoresAutomaticallyOption];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType
configuration:nil
URL:[NSURL URLWithString:#"memory://store"]
options:dict
error:&error])
{
[[NSApplication sharedApplication] presentError:error];
[persistentStoreCoordinator release], persistentStoreCoordinator = nil;
return nil;
}
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:dict
error:&error])
{
[[NSApplication sharedApplication] presentError:error];
[persistentStoreCoordinator release], persistentStoreCoordinator = nil;
return nil;
}
ASSIGN new created objects to in-Memory store
NSManagedObject *objectCarrier = [NSEntityDescription
insertNewObjectForEntityForName:#"Carrier"
inManagedObjectContext:managedObjectContext];
[objectCarrier setValue:startForCarrier
forKey:#"name"];
NSURL *url = [NSURL URLWithString:#"memory://store"];
[managedObjectContext assignObject:objectCarrier
toPersistentStore:[[appDelegate persistentStoreCoordinator] persistentStoreForURL:url]];
SAVE FINAL OBJECT
A difference between in-memory and particular persistent store using is
i have wrong using objects from predicates for same code.
If i just change persistent store type, i pickup object:
NSManagedObject *destination = [[codeAfterComparing lastObject] valueForKey:codeRelationshipName];
But set values for this object is doesn't work.
If i try to assignObject for received object, i have error (it's doesnt matter, how this object was save as inMemory or asSqlLite store object, error is start every time).
2011-02-16 14:32:45.037 snow
server[44411:1803] * Terminating app
due to uncaught exception
'NSInvalidArgumentException', reason:
'Can't reassign an object to a
different store once it has been
saved.'
Attempt to save a final object's graph with two different stores gives me error "CoreData does not support persistent cross-store relationships", and it's doesn't matter, where cureent object assing.
Migration was as :
for (NSPersistentStore *persistentStore in [persistentStoreCoordinator persistentStores]) {
if (persistentStore.type == NSInMemoryStoreType) {
// migrate the in-memory store to a SQLite store
NSError *error;
[persistentStoreCoordinator migratePersistentStore:persistentStore toURL:[NSURL fileURLWithPath:[[self applicationSupportDirectory] stringByAppendingPathComponent:#"storedata.sql"]] options:nil withType:NSSQLiteStoreType error:&error];
if (! newPersistentStore) {
Product error: "Can't add the same store twice"
So, the result is a very strange for me:
1. Looks like managed object context have no difference for objects between 2 stores. If i ask save, it take whole object and save so same sqlite store
2. maybe a way to using different persistent store coordinator's but i don't know exactly, how is easy transfer objects between 2 stores. Of course, i can do a copy (include relationships e.t.c.) but this is a hard code for this simple issue, i guess.
Maybe somebody can suggest about my code wrong or good working examples of code to review and understand a good way to do in memory cache with core data? Google search gives not too much examples.
If you look at the Core Recipe example code on Apple's website, they use multiple stores to save objects in memory and on disk.
Thought I'd take a stab here.
I've had this problem in the past. I ended up removing the functionality for two persistent stores in the same coordinator. If I understand Apple correctly, Object Entities cannot be shared between persistent stores. So to make things easier, I usually just do the following (though I suspect there is an efficiency issue with using an additional Coordinator)
1 NSPersistentStore per NSPersistentStoreCoordinator
break up the scratchpad work to the NSManagedObjectContexts
create a deep-copy method to your NSManagedObject subclasses
And then, when whatever class you have managing each persistent store utilize the copy function to import the managed objects.
I can't really think of an instance where you'd want to go through the extra trouble of individually assigning the managed objects to a specific store that wouldn't be taken car of in this way.
I have a program that utilizes two stores - one in memory for transient objects and another managing the document. It's working just fine.
In iOS 5 Apple introduce Nested Managed Object Contexts where you can work with two Managed Object contexts.
This may replace your approach with the in memory store because e.g. you can now use one of the (also) new concurrency types to run one context in the background (e.g. for background fetching) and another as your main context.
Take a look in the WWDC2011 Session 303.
I have several subclasses of NSManagedObject. They are all instantiated with code something like this:
MeasurementDescriptor *descriptor = (MeasurementDescriptor *)[NSEntityDescription
insertNewObjectForEntityForName:#"MeasurementDescriptor"
inManagedObjectContext:context];
or like this:
Experiment *experiment = (Experiment *)[NSEntityDescription
insertNewObjectForEntityForName:#"Experiment"
inManagedObjectContext:context];
What is odd, though, is that (from code above)
NSLog(#" descriptor's class = %#", NSStringFromClass([descriptor class]));
prints out 'NSManagedObject', while
NSLog(#" experiment's class = %#", NSStringFromClass([experiment class]));
prints out 'Experiment'.
Does anyone know why this would be? MeasurementDescriptor, unlike my other NSManagedObject subclasses, had no ivars (not including its Core Data properties). Adding an ivar did not change anything. Similarly, MeasurementDescriptor is the only NSManagedObject subclass without 'relationship' properties. Perhaps this accounts for this strangeness...???
The only explaination is that your MeasurementDescriptor subclass is not actually known to the code. The most common causes of this are:
In the data model editor not setting the Class attribute of the entity to the correct class.
Not adding the source file for the subclass to the target.
This is easy to do with Core Data because if it can't find a dedicated subclass it doesn't complain but just returns a generic NSManagedObject initialized with the entity's property key names.