Initializing a Store and Loading Data
This article provides details of how to initialize a persistent store and to load data from an URL.
Initializing a Store
When you add a store to a persistent store coordinator, the store is initialized with initWithPersistentStoreCoordinator:configurationName:URL:options:
. After a store is initialized, it receives a request from the persistent store coordinator to load its data through the load:
method.
You are not required to implement initWithPersistentStoreCoordinator:configurationName:URL:options:
—in some situations the default implementation will suffice. If you do need to provide additional initialization, however, you need to consider that initWithPersistentStoreCoordinator:configurationName:URL:options:
is invoked both for existing stores and for new stores.
Your implementation of initWithPersistentStoreCoordinator:configurationName:URL:options:
must be able to handle being initialized with a nil
URL and an URL that points to a zero-length file. The latter serves as an indicator that a new store is to be constructed at the specified location and allows you to securely create reservation files in known locations which can then be passed to Core Data to construct stores.
Loading a File
The load:
method is responsible for retrieving the data from the URL specified for the store and creating the necessary objects. For each element in the store, you must create:
A reference data object that contains the data from the element
A managed object ID
An atomic store cache node
Once all of the nodes have been created, you register them with the store using addCacheNodes:
.
As an example, consider a store with the following contents:
Person,Robert,Tibbot,86349382003 |
Person,Jeff,Hancock,5987749473 |
Person,Derek,Benson,7987082467 |
Person,George,Andronov,7987082467 |
Reference Data
The reference data object is simply an object representation of the data in the store. For example, you might create an NSMutableDictionary
object for each Person:
{ firstName = @"Robert", lastName = @"Tibbot", id = 86349382003 } |
{ firstName = @"Jeff", lastName = @"Hancock" id = 5987749473 } |
{ firstName = @"Derek", lastName = @"Benson" id = 7987082467 } |
{ firstName = @"George", lastName = @"Andronov" id = 3492475026 } |
Managed Object ID
You create a managed object ID using objectIDForEntity:referenceObject:
, passing entity and key data for the node. You can get the entity from the managed object model associated with the store's persistent store coordinator, for example:
NSEntityDescription *personEntity = |
[[[[self persistentStoreCoordinator] managedObjectModel] |
entitiesByName] objectForKey:@"Person"]; |
NSManagedObjectID *moID = |
[self objectIDForEntity:personEntity referenceObject:[personDictionary objectForKey: @"id"]]; |
The object ID for a cache node is also the object ID for a managed object representing the cache node. It is not necessary that the key information be encoded in the reference values, but it must be unique in the set of entity instances persisted in the store and reproducibly derivable.
Cache node
You create a cache node using the NSAtomicStoreCacheNode
method initWithObjectID:
.
NSAtomicStoreCacheNode *personNode = |
[[NSAtomicStoreCacheNode alloc] initWithObjectID:moID]; |
After creating each node, you usually push the corresponding persisted data into the node (although you can implement lazy loading or other behavior).
The cache node uses a mutable dictionary as a backing store. If when you parse the data you create instances of NSMutableDictionary
to represent each element, and the keys in the dictionary are the property names of the corresponding entity, then you can set the cache node directly:
[personNode setPropertyCache:personDictionary]; |
The values in cache node must be:
For an attribute value, instance of an attribute type supported by Core Data (see
NSAttributeDescription
);For a to-one relationship, another cache node instance;
For a to-many relationship, a collection of the related cache nodes.
Example
Consider a store with the following contents:
Person::first:Robert:last:Tibbot:id:86349382003 |
Person::first:Jeff:last:Hancock:id:5987749473 |
Person::first:Derek:last:Benson:id:7987082467 |
Person::first:George:last:Andronov:id:7987082467 |
The load:
method might first parse the file to create an NSMutableDictionary
object for each Person:
{ firstName = @"Robert", lastName = @"Tibbot", id = 86349382003 } |
{ firstName = @"Jeff", lastName = @"Hancock", id = 5987749473 } |
{ firstName = @"Derek", lastName = @"Benson", id = 7987082467 } |
{ firstName = @"George", lastName = @"Andronov", id = 3492475026 } |
and collect them in an array, personDictionaries
. In this case, the keys used in the dictionary are the same as the property names for the Person entity.
You then create the Core Data objects as follows:
NSEntityDescription *personEntity = |
[[[[self persistentStoreCoordinator] managedObjectModel] |
entitiesByName] objectForKey:@"Person"]; |
NSMutableSet *cacheNodes = [NSMutableSet set]; |
NSDictionary *objectData; |
id referenceObject; |
NSManagedObjectID *moID; |
NSAtomicStoreCacheNode *personNode; |
for (NSMutableDictionary *personDictionary in personDictionaries) { |
objectData = [personDictionary mutableCopy]; |
// The managed object itself should not store the value of the identifier as a property. |
referenceObject = [personDictionary valueForKey:@"id"]; |
[objectData removeObjectForKey: @"id"]; |
moID = [self objectIDForEntity:personEntity |
referenceObject:referenceObject]; |
personNode = [[NSAtomicStoreCacheNode alloc] initWithObjectID:moID]; |
[personNode setPropertyCache:objectData]; |
[cacheNodes addObject:personNode]; |
} |
[self addCacheNodes:cacheNodes]; |
Copyright © 2011 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2011-10-12