Skip to Content
Author's profile photo Milton Chandradas

Migration Step 2 – Offline Store

Overview Backend App Configuration Android iOS
MBO iOS App OData iOS App

OData iOS Content:

In the MBO world (depending on SUP version and device platform), you either have a local ultralite or SQLite database residing on the device.  The data from the backend EIS system is staged (or cached) in the consolidated database (CDB).  This data is then synchronized with the local database residing on the device.  All CRUD operations are performed on the local database.  So in a sense, all native MBO based applications have offline capability. When it comes to migrating MBO based application to an OData based application using the harmonized SDK, there is an implicit mapping of the offline capability inherent in MBO world to the Offline Store concept in the OData world.  Unless absolutely required by business needs, I do not recommend using both Online Store and Offline Store within the same application.  In fact for all migration needs, I strongly recommend only using the Offline Store to achieve similar functionality.

Synchronization Groups maps to Defining Requests

There is a strong correlation between synchronization groups in MBO world to the defining requests in the OData world.  Roughly speaking, a synchronization group must contain MBOs that must be synchronized at the same time.  For example, if you have SalesOrders and SalesOrderItems MBOs, then it makes sense to synchronize both these MBOs at the same time.  In this case, you would place both SalesOrders and SalesOrderItems MBO in the same synchronization group.

In our migration example, we have the following synchronization groups.


Synchronization Group









This corresponds to creating 2 defining requests in our OData mobile application.

[options addDefiningRequestWithName:@”SG_Sales” url:@”BusinessPartners?$filter=Country eq ‘US’&$expand=SalesOrders/Items” retrieveStreams:NO];

[options addDefiningRequestWithName:@”SG_Product” url:@”Product?$expand=ProductDetails retrieveStreams:NO];

Note that the $expand option is used to retrieve all the related entities in BusinessPartner, SalesOrders and SalesOrderItems.

Load Parameters and Sync Parameters maps to Query Filter

In our MBO sample application, we filtered data sent down to the device based on the Country.  This sent down only BusinessPartners that belonged to a certain country.  Since SalesOrders and SalesOrderItems follow BusinessPartners, they were also filtered and only related entries were sent down to the device.


In the OData application, the load parameters and sync parameters can be specified as query filters in the defining request.  Here we see how the BusinessPartner is filtered based on Country eq ‘US’.

@”BusinessPartners?$filter=Country eq ‘US’&$expand=SalesOrders/Items”

In some cases, the user may want data from a different country for some reason (for example, user goes on a business trip to Europe).  There is not an elegant solution to this in the OData SDK.  The current workaround is to recreate the Offline Store.

Implementing the Offline Store

Similar to the central logon handler class that was used for on-boarding a device, it is recommended to create a class that handles Offline Store functionality.  This class must implement methods to open the Offline Store and be able to flush and refresh the Offline Store.  A static variable of type SODataOfflineStore is also declared that can be used in various parts of the program using a getStore class method.

@interface ODataContext : SODataOfflineStore

+ (SODataOfflineStore *)getStore;

– (void)openOfflineStore;

– (void)flush:(void(^)(BOOL success))completion;

– (void)refresh:(void(^)(BOOL success))completion;


This class must also implement the various delegate methods associated with opening an Offline Store, flushing the contents of an Offline Store and refreshing the Offline Store protocols.

static SODataOfflineStore *STORE;

@interface ODataContext() <SODataOfflineStoreDelegate, SODataOfflineStoreRefreshDelegate, SODataOfflineStoreFlushDelegate, SODataOfflineStoreRequestErrorDelegate>


The getStore class method simply returns the static variable STORE to be used in various parts of the program.

+ (SODataOfflineStore *)getStore


    return STORE;


The UI can be updated based on the various callback methods that are associated with the protocols for opening the Offline Store, flushing and refreshing contents of Offline Store.

Implementing the callbacks

As mentioned earlier, the class that handles the Offline Store functionality must implement methods to open the store and perform flush and refresh.  Since all these operations are asynchronous in nature, the class must also handle the success and error callbacks.

– (void) offlineStoreStateChanged:(SODataOfflineStore *)store state:(SODataOfflineStoreState)newState


    switch (newState)


        case SODataOfflineStoreOpening// The store has started to open



        case SODataOfflineStoreInitializing: // The store is being initialized



        case SODataOfflineStorePopulating: // The store is being populated



        case SODataOfflineStoreDownloading: // The store is being downloaded



        case SODataOfflineStoreOpen: // The store is being opened



        case SODataOfflineStoreClosed: // The store is closed by user





– (void) offlineStoreFlushSucceeded:(SODataOfflineStore*) store


  // Flush succeeded


– (void) offlineStoreRefreshSucceeded:(SODataOfflineStore *)store


  // Refresh succeeded


Application configuration file

In addition, use an application configuration file to configure OData endpoints and defining requests that determine the data that populates the application database when it is created.









I have attached a sample application that opens the Offline Store and performs flush and refresh using the steps outlined above.  Please let me know if you have any questions.

Our next step in the migration process is querying the data. 

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.