ActiveResourceKit  v1.2 (498.0)
 All Classes Files Functions Variables Typedefs Enumerator Properties Macros Pages
Instance Methods | Class Methods | Protected Attributes | Properties | List of all members
ARIncrementalStore Class Reference

Core Data incremental store based on active resources. More...

#import <ARIncrementalStore.h>

Inheritance diagram for ARIncrementalStore:
Inheritance graph
[legend]
Collaboration diagram for ARIncrementalStore:
Collaboration graph
[legend]

Instance Methods

(ARService *) - serviceForEntityName:
 Answers a suitably-connected Active Resource service for interacting with the given entity.
 
(void) - evictAllResources
 Flushes the resource cache.
 
(NSString *) - elementNameForEntityName:
 
(NSString *) - entityNameForElementName:
 
(NSString *) - attributeNameForPropertyName:
 
(NSString *) - propertyNameForAttributeName:
 
(id) - initWithPersistentStoreCoordinator:configurationName:URL:options: [implementation]
 
(BOOL) - loadMetadata: [implementation]
 Validates the store URL.
 
(id) - executeRequest:withContext:error: [implementation]
 
(id) - executeFetchRequest:withContext:error: [implementation]
 
(id) - executeSaveRequest:withContext:error: [implementation]
 Core Data sends this message when managed-object contexts save.
 
(NSIncrementalStoreNode *) - newValuesForObjectWithID:withContext:error: [implementation]
 
(id) - newValueForRelationship:forObjectWithID:withContext:error: [implementation]
 
(NSArray *) - obtainPermanentIDsForObjects:error: [implementation]
 
(void) - cache:willEvictObject: [implementation]
 
(NSManagedObjectID *) - objectIDForResource:withContext:
 Using a particular context, derives a managed-object identifier based on a resource's element name and its primary key.
 
(NSManagedObjectID *) - objectIDForCachedResource:withContext:
 Answers the object identifier for a given resource after caching the resource against its object identifier.
 
(ARResource *) - cachedResourceForObjectID:error:
 Converts an object identifier to an active resource.
 
(uint64_t) - versionForResource:
 Answers a 64-bit version number derived from the given resource.
 
(void) - refreshObject:
 Refreshes an object in the incremental store cache.
 
(NSDictionary *) - foreignKeysForObject:resource:
 Resolves relationships.
 

Class Methods

(NSString *) + storeType
 
(void) + registerStoreClass
 
(NSString *) + storeTypeForClass:
 Derives a store's type for use when adding a store instance to your persistent store coordinator.
 
(void) + registerStoreTypeForClass:
 Registers an incremental store subclass.
 
(void) + initialize [implementation]
 

Protected Attributes

NSCache *__strong _resourcesByObjectID
 Caches resources by object ID.
 

Properties

NSString * entityNamePrefix
 Optional prefix string for entity names.
 

Detailed Description

Core Data incremental store based on active resources.

The ARIncrementalStore class performs one simple function: translating Core Data requests to Active Resource requests, and translating Active Resource responses to Core Data responses. The class mediates between Core Data and Active Resource. You can easily access remote resources using Core Data by hooking up an ARIncrementStore-type store to your Core Data context. Specify the site URL when you add the store. The store automatically derives the resources and their properties using the managed-object model along with standard Rails-compatible conventions for naming.

Definition at line 40 of file ARIncrementalStore.h.

Method Documentation

- (NSString *) attributeNameForPropertyName: (NSString *)  propertyName

Definition at line 132 of file ARIncrementalStore.m.

- (void) cache: (NSCache *)  cache
willEvictObject: (id)  obj 
implementation

Definition at line 641 of file ARIncrementalStore.m.

- (ARResource *) cachedResourceForObjectID: (NSManagedObjectID *)  objectID
error: (NSError **)  outError 

Converts an object identifier to an active resource.

The conversion occurs using the resource cache, if the resource currently exists in the cache (a cache hit). Otherwise the implementation first loads the cache with the resource using the given object identifier (a cache miss). Uncached resources become cached before the method returns.

Provided by category ARIncrementalStore(Private).

Definition at line 46 of file ARIncrementalStore+Private.m.

- (NSString *) elementNameForEntityName: (NSString *)  entityName

Definition at line 108 of file ARIncrementalStore.m.

- (NSString *) entityNameForElementName: (NSString *)  elementName

Definition at line 122 of file ARIncrementalStore.m.

- (void) evictAllResources

Flushes the resource cache.

Removes all resources currently retained by the incremental store's active resource-oriented cache. Note that this method flushes the resource cache only. It does not fault any associated non-fault managed objects which also retain client-side snapshots of attributes and relationships. Resources do not persist in the cache for any length of time; managed objects cache remote resources independently when not faulted. The cache exists as an interface bridging device for marrying Active Resource protocols with Core Data protocols.

Definition at line 97 of file ARIncrementalStore.m.

- (id) executeFetchRequest: (NSFetchRequest *)  request
withContext: (NSManagedObjectContext *)  context
error: (NSError **)  outError 
implementation
Returns
If the request is a fetch request whose result type is set to one of NSManagedObjectResultType, NSManagedObjectIDResultType, NSDictionaryResultType, returns an array containing all objects in the store matching the request. If the request is a fetch request whose result type is set to NSCountResultType, returns an array containing an NSNumber of all objects in the store matching the request.

This method runs on iOS, for instance, when a fetched results controller performs a fetch in response to a table view controller determining the number of sections in the table view.

Fetch Request State
Executing a fetch request requires decoding the fetch request. Fetch requests include numerous additional parameters, including:
  • group-by properties
  • predicate
  • values to fetch
  • entity description
  • offset
  • sort descriptors
  • batch size
  • fetch limit
  • relationship key paths for pre-fetching
  • flags

Requests can be complex. In Objective-C terms, you can acquire the full fetch-request state using:

NSString *entityName = [request entityName];
NSPredicate *predicate = [request predicate];
NSArray *sortDescriptors = [request sortDescriptors];
NSUInteger fetchLimit = [request fetchLimit];
NSArray *affectedStores = [request affectedStores];
NSFetchRequestResultType resultType = [request resultType];
BOOL includesSubentities = [request includesSubentities];
BOOL includesPropertyValues = [request includesPropertyValues];
BOOL returnsObjectsAsFaults = [request returnsObjectsAsFaults];
NSArray *relationshipKeyPathsForPrefetching = [request relationshipKeyPathsForPrefetching];
BOOL includesPendingChanges = [request includesPendingChanges];
BOOL returnsDistinctResults = [request returnsDistinctResults];
NSArray *propertiesToFetch = [request propertiesToFetch];
NSUInteger fetchOffset = [request fetchOffset];
NSUInteger fetchBatchSize = [request fetchBatchSize];
BOOL shouldRefreshRefetchedObjects = [request shouldRefreshRefetchedObjects];
NSArray *propertiesToGroupBy = [request propertiesToGroupBy];
NSPredicate *havingPredicate = [request havingPredicate];

Definition at line 233 of file ARIncrementalStore.m.

- (id) executeRequest: (NSPersistentStoreRequest *)  request
withContext: (NSManagedObjectContext *)  context
error: (NSError **)  outError 
implementation

Definition at line 171 of file ARIncrementalStore.m.

- (id) executeSaveRequest: (NSSaveChangesRequest *)  request
withContext: (NSManagedObjectContext *)  context
error: (NSError **)  outError 
implementation

Core Data sends this message when managed-object contexts save.

The save-changes request encapsulates inserted, updated and deleted objects.

Definition at line 346 of file ARIncrementalStore.m.

- (NSDictionary *) foreignKeysForObject: (NSManagedObject *)  object
resource: (ARResource *)  resource 

Resolves relationships.

Picks out the to-one associations. Is there a foreign key with a matching to-one relationship? Looks for a matching foreign key within the resource for each to-one relationship. If the foreign key does not exist but the to-one relationship does, then resolves the relationship at the server side by assigning the foreign key to the relationship destination's object reference, its resource identifier. Collects such foreign key attributes first because there could be multiple. Merge and save them.

Ignores to-many associations. Rails will handle that.

Provided by category ARIncrementalStore(Private).

Definition at line 91 of file ARIncrementalStore+Private.m.

+ (void) initialize
implementation

Definition at line 46 of file ARIncrementalStore.m.

- (id) initWithPersistentStoreCoordinator: (NSPersistentStoreCoordinator *)  root
configurationName: (NSString *)  name
URL: (NSURL *)  URL
options: (NSDictionary *)  options 
implementation

Definition at line 75 of file ARIncrementalStore.m.

- (BOOL) loadMetadata: (NSError **)  outError
implementation

Validates the store URL.

Is the store URL usable? Does it exist? Can the store receive save requests? Are the schemas compatible?

Definition at line 155 of file ARIncrementalStore.m.

- (id) newValueForRelationship: (NSRelationshipDescription *)  relationship
forObjectWithID: (NSManagedObjectID *)  objectID
withContext: (NSManagedObjectContext *)  context
error: (NSError **)  outError 
implementation

Definition at line 504 of file ARIncrementalStore.m.

- (NSIncrementalStoreNode *) newValuesForObjectWithID: (NSManagedObjectID *)  objectID
withContext: (NSManagedObjectContext *)  context
error: (NSError **)  outError 
implementation

Definition at line 472 of file ARIncrementalStore.m.

- (NSManagedObjectID *) objectIDForCachedResource: (ARResource *)  resource
withContext: (NSManagedObjectContext *)  context 

Answers the object identifier for a given resource after caching the resource against its object identifier.

Provided by category ARIncrementalStore(Private).

Definition at line 39 of file ARIncrementalStore+Private.m.

- (NSManagedObjectID *) objectIDForResource: (ARResource *)  resource
withContext: (NSManagedObjectContext *)  context 

Using a particular context, derives a managed-object identifier based on a resource's element name and its primary key.

Derives the entity name from the resource element name.

Provided by category ARIncrementalStore(Private).

Definition at line 32 of file ARIncrementalStore+Private.m.

- (NSArray *) obtainPermanentIDsForObjects: (NSArray *)  objects
error: (NSError **)  outError 
implementation

Invoked just before sending a save-changes request. Objects sent here have only a temporary object ID. Objective: to assign permanent IDs to newly inserted objects. Answers a set of matching object IDs. The implementation assumes that the given object's have IDs always of nil. It sends Active Resource "create with attributes" requests for each object in order to obtain each object's permanent ID, as assigned by the resource server.

There is a synchronisation issue here. The given objects do not yet exist at the server side; they have no permanent identifiers and hence Core Data asks for those identifiers by invoking this override. The objects need creating. Their permanent identifiers appear at the server side when the remote application creates the associated record.

Definition at line 607 of file ARIncrementalStore.m.

- (NSString *) propertyNameForAttributeName: (NSString *)  attributeName

Definition at line 137 of file ARIncrementalStore.m.

- (void) refreshObject: (NSManagedObject *)  object

Refreshes an object in the incremental store cache.

Parameters
objectThe object to refresh.

The given object disappears from the resource cache and becomes a fault. Subsequent attempts to access the object will refetch its resource attributes. This happens when objects insert. Inserted objects become unrealised because the remote server typically validates and further updates the inserted resource, e.g. by setting its update-at date. It also occurs when you update an object, for the same reason. Object deletion also refreshes the cache; the deleted resource disappears from the cache and the object becomes a fault before disappearing from the managed-object context as all deleted objects do.

Provided by category ARIncrementalStore(Private).

Definition at line 85 of file ARIncrementalStore+Private.m.

+ (void) registerStoreClass

Definition at line 59 of file ARIncrementalStore.m.

+ (void) registerStoreTypeForClass: (Class)  aClass

Registers an incremental store subclass.

You need to register the store class before using it. If your run-time loading sequence prevents you registering the store type automatically during class initialisation, that is, during +initialize, then in such cases you need to invoke +registerStoreTypeForClass:aClass explicitly before using the store type. Typically though, you can register the store type during class initialisation. Your sub-class interface will contain method declarations along these lines:

+ (NSString *)storeType;

Along with implementations as follows:

+ (void)initialize
{
if (self == [MyActiveResourceIncrementalStore class])
{
}
}
+ (NSString *)storeType
{
return [ARIncrementalStore storeTypeForClass:self];
}
{
[ARIncrementalStore registerStoreTypeForClass:self];
}

Definition at line 69 of file ARIncrementalStore.m.

- (ARService *) serviceForEntityName: (NSString *)  entityName

Answers a suitably-connected Active Resource service for interacting with the given entity.

Performs Core Data entity-name to Active Resource element name mapping. Uses a standard delegate-based URL connection. The connection runs asynchronously but delegates synchronously and conveniently handles authentication if needed.

Definition at line 87 of file ARIncrementalStore.m.

+ (NSString *) storeType

Definition at line 54 of file ARIncrementalStore.m.

+ (NSString *) storeTypeForClass: (Class)  aClass

Derives a store's type for use when adding a store instance to your persistent store coordinator.

You could define this explicitly but there exists an essential requirement. It is very important that the store-type string matches the class name. If not, your store will fail to successfully attach to its store coordinator. Core Data's error reason explains, "The store type in the metadata does not match the specified store type." Make them match to avoid this error. Best way to make them match? Make store type equal to class name.

Definition at line 64 of file ARIncrementalStore.m.

- (uint64_t) versionForResource: (ARResource *)  resource

Answers a 64-bit version number derived from the given resource.

Uses the updated-at date-time as the version number. Converts the update-at date to seconds since the reference date. This amounts to a big version number, but the version number allows for 64 bits of unsigned integer width.

Also makes an assumption about the updated-at dates: that they always exceed midnight 1st January 2001, the reference point. If they precede that point, then the reference-relative time interval becomes negative, the signed interval wraps the unsigned 64-bit version and version numbers start counting down. This is not what Core Data will expect.

The implementation multiplies the time interval by 1,000 in order to allow for rare sub-second updates, if the server-side includes date-time at sub-second resolutions. RFC 3339 date-time formats allow for sub-second accuracy.

Provided by category ARIncrementalStore(Private).

Definition at line 70 of file ARIncrementalStore+Private.m.

Member Data Documentation

- (NSCache* __strong) _resourcesByObjectID
protected

Caches resources by object ID.

This cache effectively associates Active Resource with Core Data. It bridges the difference between the Active Resource interface and the Core Data interface. When you "find" active resources, all resource attributes become available. However, when Core Data fetches managed objects incrementally, the incremental-store interface expects only object IDs at first. Subsequently, Core Data asks for attribute and relationship values, i.e. entity properties. This cache exists to buffer those values until Core Data requests them.

Same goes when instantiating new object-resource pairs. The Active Resource interface creates a new resource along with its attributes. Core Data, however, only obtains permanent IDs initially. They become faulted objects. Core Data asks for properties later when needed. Again, the resources-by-object-ID cache acts as a bridging buffer.

Definition at line 60 of file ARIncrementalStore.h.

Property Documentation

- (NSString*) entityNamePrefix
readwriteatomiccopy

Optional prefix string for entity names.

In the Objective-C world, entity names often begin with a namespace prefix. If this is the case, specify the prefix here. The incremental store automatically adds or removes the prefix when translating between entity names and element names. For example, your element names might be post and comment when accessing some kind of RESTful blog interface. But your Objective-C entities might be MYPost and MYComment. Configure your store's entity name prefix as MY and it will automatically prepend MY when converting from element to entity names; and automatically remove it when converting from entity to element names.

Definition at line 151 of file ARIncrementalStore.h.


The documentation for this class was generated from the following files: