NSIncrementalStore Tutorial for iOS: Getting Started

Learn how you can use the very powerful NSIncrementalStore to provide Core Data with a completely custom data storage option. By Rony Rozen.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Working With Web Services

Now that your fetch and save requests are running customized logic you defined, you can be flexible with your datastore instead of accessing a local SQLite database directly. One popular use case for this newly-found freedom is making network requests to fetch and update remote objects.

If, tomorrow morning, you woke up and decided to upgrade this app to use a remote database on your server, you’d simply need to change the implementation of the fetch and load requests. Your app doesn’t even need to know that the underlying database implementation has changed.

Working with a remote database introduces several new challenges:

  • Since you’ll be relying on remote objects, you need to make sure to consider latency. If you’re used to making requests on the main thread, you’ll need to reconsider your approach. Since network calls shouldn’t be made on the main thread, as it blocks the UI, your Core Data code now needs to move to a background thread. Working with Core Data on multiple threads introduces additional challenges.
  • Make sure your app can handle poor or non-existent network availability.

To help you with these, you can use the Instruments app to test your app thoroughly in multiple use cases and network conditions to ensure your custom incremental data store meets your needs.

Best Practices And Gotchas

Someone wise once said that “with great power comes great responsibility.”

Incremental stores give you the tools you need to work with large complex data stores. This section will introduce you to some best practices to maximize the performance and efficiency of your custom incremental stores.

Caching

Use caching in a way that best matches your app’s characteristics and needs. Some rules of thumb:

  • Prefetch and cache values for fetch requests if your backing store can efficiently return complete (unfaulted) objects in a single request.
  • Batch request objects if one large request is faster than multiple smaller requests, instead of creating an individual request each time a fault is fired on an object. This is usually true when working with remote databases.
  • Write the cache to disk if the availability of your backing store is unreliable or if requests are slow. That way, you’ll be able to immediately respond to requests and update the data later by posting a notification for the UI to refetch when the updated data is available.

Relationships

The Saving Data section of this NSIncrementalStore tutorial mentioned the newValuesForObjectWithID:withContext:error: function for retrieving values of properties for faulted fetched objects. This method is used for “to-one” relationship faults.

If your data model contains “to-many” relationships, you’ll need to use newValuesForRelationship:forObjectWithID:withContext:error: for fulfilling faults. You can use the relationship’s name property to identify the relevant relationship, and fetch the relevant unique identifiers from your backing store.

Optimistic Locking and Memory Conflicts

Core data offers a mechanism to detect in-memory conflicts and when another client has made changes to the backing store. This mechanism is called optimistic locking.

Resolving In-Memory Conflicts: When working with multiple contexts on multiple threads, changes are only merged when the contexts are saved to the store, depending on the provided merge policy.

To facilitate the persistent store coordinator’s in-memory locking mechanism, your incremental store needs to store a number for each record and increment it every time that record is saved.

Resolving In-Storage Conflicts: Your custom incremental store is responsible for detecting conflicts in the backing data, due to changes made by another client.

To resolve these issues, you should use the NSMergeConflict class (reference).

Where To Go From Here?

You can download the completed project for this tutorial here.

For additional information, I recommend checking out Apple’s official Incremental Store Programming Guide.

Also, If you enjoyed this NSIncrementalStore tutorial, you’ll definitely enjoy our book Core Data by Tutorials.

The book covers additional aspects of Core Data and is written for intermediate iOS developers who already know the basics of iOS and Swift development but want to learn how to leverage Core Data to persist data in their apps.

I hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!