Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
kenichi_unnai
Advisor
Advisor




Ladies and Gentlemen,

 

Time to start the offline scenario. Before jumping in the new API, let's recall the formal description about what the ODataStore is.

The ODataStore is covering exactly one OData service (service document and metadata). It shall be possible for an application to create multiple ODataStores (also in combination on- and offline) at the same time, which shall be completely independent from the API perspective and have own life cycles.

 

For online we use SODataOnlineStore. For offline, we need to understand another store object called SODataOfflineStore.

Both stores declare SODataStoreAsync protocol, this means SODataOfflineStore can use the same CRUD methods with SODataOnlineStore.

 

Let's have a look at how we create SODataOfflineStore:

01  SODataOfflineStore *offlineStore = [[SODataOfflineStore alloc] init];
02  SODataOfflineStoreOptions *options = [[SODataOfflineStoreOptions alloc] init];
03  options.host = serverHost;
04  options.port = serverPort;
05  options.serviceRoot = [NSString stringWithFormat:@"/%@", applicationId];
06  options.conversationManager = myConversationManager;
07  options.storeEncryptionKey = @"MyEncryptionKey";
08  [options addDefiningRequestWithName:@“req1” url:@"/CarrierCollection" retrieveStreams:false];
09  ..
10  [offlineStore setOfflineStoreDelegate:self];
11  [offlineStore openStoreWithOptions:options error:&error];

Once you get familiar with SODataOnlineStore, it should be pretty easy. The difference is we supply option values via ODataOfflineStoreOptions, by which we set the values like SMP server host name or HttpConversationManager.

 

#07 is the optional parameter, which encrypts the store. If you don't set it explicitly, the store won't get encrypted. You only need to provide it to the store options. After that, the library takes care of encrypting/decrypting all of the content.

 

You have noticed a new line "addDefiningRequestWithName" in #08. The defining requests define the entire set of data that will be available to read out of the store (we'll discuss the detail in the next blog). You can add as many defining requests as you like. The value is OData URLs, relative to the service root. The last retrieveStreams param is the new feature from SP8 - if it is true, it downloads the media resources.

For ODataOfflineStore, we use another delegate protocol named SODataOfflineStoreDelegate. For this example the delegate is declared in its own class, so simply set self. Finally we can try to open the offline store by openStoreWithOptions: which triggers following callback methods:

  • offlineStoreStateChanged:state:  Called when the store state changes.

  • offlineStoreOpenFailed:error: Called if the store fails to open.


And two optional callback methods:

  • offlineStoreOpenFinished: Called when the store finishes opening (for both success and failed).

  • offlineStoreNotification:notification:  (Bonus explanation in the bottom part of this blog) Called once for each notification that is generated during the open.


 

The offlineStoreStateChanged:state: callback method keeps us informed what the current status is.
01  - (void) offlineStoreStateChanged:(SODataOfflineStore *)store state:(SODataOfflineStoreState)newState
02  {
03    switch (newState) {
04      case SODataOfflineStoreOpening: 
05      break;
06
07      case SODataOfflineStoreInitializing:
08      break;
09    
10      case SODataOfflineStorePopulating:
11      break;
12    
13      case SODataOfflineStoreDownloading:
14      break;
15    
16      case SODataOfflineStoreOpen:
17      // the offline store has opened...read the OData
18      break;
19    
20      case SODataOfflineStoreClosed:
21      break;
22    }
23  }

Once it reaches the SODataOfflineStoreOpen state, the offline store is ready.

 

Tip: Make sure to call GlobalInit and GlobalFini at the beginning and ending of the app code to use SODataOfflineStore.
01  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
02  {  
03    [SODataOfflineStore GlobalInit];
04     ...
05  }

01  - (void)applicationWillTerminate:(UIApplication *)application
02  {
03    [SODataOfflineStore GlobalFini];
04  }

Congratulations, now you have successfully obtained the offline store. As explained, this store can use the same CRUD methods you had learned in the blog #03 and #04. The difference is one important fact - this store has the "offline" state. What does that mean to the API? We'll discuss it in the next blog.

See you in the next blog,

Ken

 

PS. Additional explanation of offlineStoreNotification:notification: method -

 

Currently, there are only two possible notifications and they indicate that either a refresh or a flush (both will be covered in the next blog) was in progress when the store was previously closed and that the store may be able to continue these operations where it left off if the application calls the refresh/flush operation again.  The advantage to doing this is to save on bandwidth and processing since you are picking up where you left off from last time instead of starting the entire process from a scratch.

 

List of blogs


22 Comments