Using the AWS Persistence Framework for Core Data

The Apple Core Data Framework provides generalized and automated solutions to common tasks associated with object life-cycle and object graph management, including persistence. You can read more about Core Data in the Apple documentation here.

Amazon DynamoDB is a fast, highly scalable, highly available, cost-effective, non-relational database service. Amazon DynamoDB removes traditional scalability limitations on data storage while maintaining low latency and predictable performance.

The AWS Persistence Framework for Core Data bring these two technologies together to allow iOS developers to write Core Data applications that use Amazon DynamoDB as a persistence backend.

Adding the AWS Persistence Framework for Core Data to Your Project

The AWS Persistence Framework for Core Data is compatible with iOS versions 5.0 and later.

Adding the AWS Persistence Framework for Core Data to your project is no different than adding any other framework to your project. After creating your Core Data enabled application, navigate to your project properties and go to the Build Phases tab. Select Link Binary With Libraries and hit the plus button to add both of the following frameworks:

Configuring the AWS Persistence Framework for Core Data

After creating your Entity/Relationship model and generating your NSManagedObject subclasses, you will need to configure the persistence store in your application.

Your application will need to register that it will use Amazon DynamoDB as its backend store. This can all be placed in the AppDelegate, as part of the persistentStoreCoordinator selector.

[NSPersistentStoreCoordinator registerStoreClass:[AWSPersistenceDynamoDBIncrementalStore class]
                                    forStoreType:AWSPersistenceDynamoDBIncrementalStoreType];
    
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

Your application will need to create a number of mappings to allow the Framework to understand how to handle its managed objects. These include:

With the mappings created, you next create a larger options dictionary. You also need to create an Amazon DynamoDB client object with AmazonCredentialProvider, and include it in the options dictionary. The AWS Persistence Framework for Core Data uses this client object to make requests to Amazon DynamoDB.

AmazonClientManager *provider = [AmazonClientManager new];
AmazonDynamoDBClient *ddb = [[AmazonDynamoDBClient alloc] initWithCredentialsProvider:provider];

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         hashKeys, AWSPersistenceDynamoDBHashKey, 
                         versions, AWSPersistenceDynamoDBVersionKey,
                         tableMapper, AWSPersistenceDynamoDBTableMapper,
                         ddb, AWSPersistenceDynamoDBClient, nil];    

Finally your application will need to pass this options dictionary to the persistance store and check for error.

    
    
if(![persistentStoreCoordinator addPersistentStoreWithType:AWSPersistenceDynamoDBIncrementalStoreType 
                                             configuration:nil 
                                                       URL:nil 
                                                   options:options 
                                                     error:&error])
{
    // Handle the error.
    NSLog(@"error: %@", error);
}
    

Conflict Management

When using the AWS Persistence Framework for Core Data on multiple threads or devices, you may encounter a situation where you need to resolve inconsistencies between data on Amazon DynamoDB tables and your local copy in memory. When the conflicts are detected, NSManagedObjectContext returns an NSError object and your change will not be persisted. You can change this behavior by setting a merge policy to your NSManagedObjectContext:

managedObjectContext.mergePolicy = [[[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyStoreTrumpMergePolicyType] autorelease];

There are five NSMergePolicyTypes available: NSErrorMergePolicyType (default), NSMergeByPropertyStoreTrumpMergePolicyType, NSMergeByPropertyObjectTrumpMergePolicyType, NSOverwriteMergePolicyType, and NSRollbackMergePolicyType. The AWS Persistence Framework for Core Data can handle all five merge policy types. For more information about NSMergePolicy, please read NSMergePolicy Class Reference.

Because NSManagedObject instances returned by Core Data are lazily loaded, it is possible that when you access an attribute of an object, the actual row in the Amazon DynamoDB table has been already deleted. In this situation, the AWS Persistence Framework for Core Data will return an empty NSManagedObject (the accessor will return nil) and sends out AWSPersistenceDynamoDBObjectDeletedNotification. You can register to observe AWSPersistenceDynamoDBObjectDeletedNotification by calling the following method:

[[NSNotificationCenter defaultCenter] addObserver:self
	selector:@selector(mergeDeletedObject:)
	name:AWSPersistenceDynamoDBObjectDeletedNotification
	object:nil];

When you receive the notification, you should remove any invalid objects from local cache and refresh the NSManagedObject instance as necessary. The notification object has a userInfo dictionary, which you can use to identify the deleted object, containing:

The following line shows how to refresh an NSManagedObject. Please note that refreshing an NSManagedObject will send a getItem request to the Amazon DynamoDB.

[managedObjectContext refreshObject:managedObject mergeChanges:YES];

Under heavily concurrent environments, periodically calling the refreshObject method may reduce inconsistent states. Also, calling the refreshObject method before saving the change will minimize inconsistent states to be persisted to the Amazon DynamoDB tables.

Limitations

Although the AWS Persistence Framework for Core Data was developed to meet the widest use case possible, it does have certain limitations.

Questions?

Please feel free to ask questions or provide comments in the Mobile Development Forum.