Caching model data

The Model Manager

iOS Buy SDK 2.0 introduces a new property of the BUYClient: modelManager. The SDK includes a default implemention with the BUYModelManager class. Most users of the SDK do not need to interact directly with this object. The BUYClient class creates one automatically for its own use.

Buy SDK 2.0 includes a new way to handle JSON serialization. The model manager is part of this new system. Again, most users of the SDK should not have to interact with the JSON serialization code.


This is an advanced topic. If you want to support client-side caching in your app, you should be familiar with Core Data, SQLite, or similar technologies.

Declarative Model

In Buy SDK 2.0 for iOS, the data model is defined in a model description file. If you have used Core Data, you will be familiar with using this file to define Core Data entities. While Core Data is designed for data persistence, the model definition file, and the NSManagedObjectModel class (and related classes like NSEntityDescription) work perfectly well without a persistence stack. In the SDK, we use the model definition file to generate custom model classes and to support JSON serialization. Of course, this is also convenient if your app wants to store model objects in a Core Data persistent store.

Support for Caching

In order to support persistence using the model manager design, you will want to implement a custom class that adopts the BUYModelManager protocol. This object will be responsible for storing objects in, and restoring objects from, your custom data store. A simple model manager might save only carts to ensure they persist across app launches. A more advanced implementation could cache catalog data (collections, products, product variants, etc.). However, you should be careful about storing checkouts, or other objects related to checkout, in a persistent store. These objects can become stale quite quickly. It is much safer to keep only a single, in-memory copy of the most up-to-date checkout returned from the Shopify API.

If you store customers or orders in a local data store, you should ensure that you delete them when your customer logs out of the app.

Core Data

If you want to support a Core Data persistent store in your app, you should enable Core Data support in the SDK by choosing the appropriate build configurations in your Xcode build scheme. The configurations that enable Core Data support end in "-core-data": "Debug-core-data" and "Release-core-data". (Please see Apple's Xcode documentation for information about schemes, configurations, and how to set the configuration for a scheme.) These configurations enable the CORE_DATA_PERSISTENCE flag.

The entities defined in the model definition file are grouped into two model configurations: one for transient entities, and the other for persistent entities. (Model configurations are completely different from Xcode build configurations. See Apple's Core Data documentation for information about model configurations.) The transient entities include Checkout and its children. They inherit from the BUYObject class. All other entities—Shop, Collection, Product and children, Customer and Address—are persistent. They inherit from the BUYManagedObject class. Both BUYObject and BUYManagedObject classes adopt the BUYObject protocol.

The BUYObject protocol has been revised to support dynamic JSON serialization. Model objects have a reference to their model manager, which, for transient objects, must be set by the model manager when a model object is created. (In the case of persistent objects, this is a simple cover for the model manager property of the NSManagedObjectContext). This ensures that related models are properly serialized and deserialized when being passed over the network. It also ensures that any local caching can support object uniquing by always fetching an existing object from the cache, if it exists, before creating a new copy.

Model objects should always be created via the BUYModelManager methods, to ensure that they are configured correctly. Otherwise, if their modelManager property is not set, neither JSON serialization nor local caching, if implemented, will work correctly for relationships.