• 3 min read

Announcing General Availability of iOS Offline Sync SDK

Most mobile apps don't work without a network connection. Learn how to use Mobile Services offline sync on iOS, and create responsive and robust apps that work, even when your network doesn't.

Don’t you hate it when your mobile app suddenly stops working, just because you’ve stepped on an elevator?  Or, maybe you’re a traveling sales rep who needs quick access to customer data, even when you’re in a dead zone. End users want apps that work, even when their network doesn’t. Unfortunately, many apps have limited or no functionality when a device is offline, mainly because it’s quite challenging to correctly implement sync behavior. What should be cached on the device?  How will the app know it should fetch new data?  What happens if data is modified while the user is offline, but they have already made local edits?

Mobile Services offline sync is designed to solve these problems, with cross-platform client SDKs that handle all of these complexities for you. Using Mobile Services, developers can easily provide a native sync experience across iOS, Android, Xamarin, and Windows apps.

We are excited to announce the general availability of the Mobile Services iOS 2.0 SDK, which adds these new sync features for native iOS. Offline sync is already available in the managed client SDK for Windows, Xamarin iOS, and Xamarin Android, and in the preview Android SDK. We’ve updated the quickstarts in the Azure portal to make it even easier to use the feature. The Objective-C iOS quickstart is now offline-enabled, along with those for Windows, Xamarin iOS, and Xamarin Android.

Offline sync offers many benefits:

  • Improve app responsiveness by caching server data locally on the device
  • Create robust apps that can handle transient network issues
  • Sync data across multiple devices and detect conflicts when the same record is modified by two devices
  • Reduce data use, particularly for metered connections

When your app is in offline mode, users can still create and modify data, which will be saved to a local store. When the app is back online, it can synchronize local changes with the Mobile Services backend. The feature also includes support for detecting conflicts when the same record is changed on both the client and the backend. Conflicts can then be handled either on the server or the client. Offline sync is very lightweight; for example, it doesn’t require storing the sync state of all mobile clients in the backend database. If you’re already using Azure Mobile Services, you can make your app offline-enabled by following these tutorials:

Your app should enable Core Data and define a model for both your app data objects and the system tables required by the SDK. In your app’s initialization logic (such as QSTodoService.init in the iOS quickstart), you will create a mobile services local store and associate it with the sync context:

// create a Mobile Services local store based on the app's Core Data model
MSCoreDataStore *store = [[MSCoreDataStore alloc] initWithManagedObjectContext:context]; 

// associate store with sync context 
self.client.syncContext = 
    [[MSSyncContext alloc] initWithDelegate:nil
                                 dataSource:store 
                                   callback:nil]; 
        
// Create an MSSyncTable instance to allow us to work with the TodoItem table
self.syncTable = [_client syncTableWithName:@"TodoItem"];

The app should now use this MSSyncTable instance (rather than MSTable) for all CRUD operations. Reads will fetch from local storage, and all Create, Update and Delete operations will be queued to be sent to the server. To send these queued changes, use the pushWithCompletion method. This is a method on the sync context and will replay all modifications in order:

[self.client.syncContext pushWithCompletion:^(NSError *error) { ... } ]

To get new changes from the server, use the pullWithQuery method:

[self.syncTable pullWithQuery:query 
                      queryId:@"allTodoItems" 
                   completion:^(NSError *error) { ... } ]

If there are any pending changes for the sync table when doing a pull operation, then the SDK will first push all changes. To enable incremental sync, use the queryID parameter. A query ID is a descriptive string that should be unique for each query in your program; it’s used internally by the SDK to store a last-modified timestamp from the last pull operation. Subsequent pull operations will only retrieve records newer than this timestamp.

The pullWithQuery method also allows you to specify a particular subset of data that should be saved to the device. In the quickstart example, all todo items are retrieved, as it is a simple data model. But, suppose we added a field to denote the importance of a todo item. Then, the app could use the appropriate query to pull only high and normal importance items. Since the local store is using Core Data, you can use NSFetchedResultsController to integrate with your view controller using key-value observing. The iOS quickstart shows an example of this by connecting the table view to the Core Data managed object context. To learn more about offline sync in iOS and on other platforms, check out the following resources: