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: 
miltonc
Product and Topic Expert
Product and Topic Expert

Update: The code for the sample application is now published.

In this blog, I will be talking about offline support for Windows.  If you have been following my other blogs (or corresponding blogs for Android and iOS), you are already aware of the concept of a Store.  You are probably aware that there is an Online Store and by extension, an Offline Store.  Although I haven’t talked about an Offline Store explicitly, I have made a few subtle references to its existence in my previous blogs.  An astute reader might have already guessed that an Online Store can be used when the device has network connection.  So what about the Offline Store?  A common mistake most people make, is that they only associate Offline Store with no network connection.  While this is true (Offline Store is used with no network connection), an Offline Store can also be used when there is network connection. In fact, I would recommend using the Offline Store in all cases (if you want offline support) – and not use the Online Store at all.  Of course, this would also depend on the business needs.  But using the Offline Store regardless of network connectivity reduces the complexity of switching back and forth between Online and Offline Stores.  The caveat is that the user might be working with stale data.

Comparing Online and Offline Stores

In the table below, I roughly compare the features of an Online Store and an Offline Store.

Online Store

Offline Store

Can work with network connection only

Can work regardless of network connectivity

Opening Online Store – straightforward

Opening Offline Store – requires more options

HTTP request – roundtrip to server

HTTP request – reads from local ultralite database

Very basic persistence using Technical Cache

Full-fledged persistence using ultralite database

CRUD operations – accomplished by OData calls

CRUD operations – OData calls are intercepted and converted to SQL calls and executed against ultralite database

No data latency

Data latency exists

No concept of flush

Flush method pushes changes made locally to the backend

No concept of refresh

Refresh method pushes changes made on the backend to the local ultralite database

Data conflicts – very minimal

Data conflicts – a real possibility

HTTP(S) protocol to transfer data between SMP Server and device

Mobilink protocol to transfer data between SMP Server and device

What happens when I open an Offline Store?

The first time an Offline Store is opened, a lot of things happen.  The Offline Store connects to the SMP Server and sends it the defining request.  It is very critical to understand what constitutes a defining request.  A defining request is an URL representing data fetched by an HTTP GET method that needs to be persisted.  An application can have multiple defining requests.

Examples of defining requests…  Note that each defining request corresponds to a single GET request.

  • Request 1 = BusinessPartners?$expand=SalesOrders/Items
  • Request 2 = SalesOrders(‘0500000002’)?expand=Items
  • Request 3 = Products?$expand=ProductDetails

Request 1

BusinessPartners

  • Rows 1, 2, 3

SalesOrders

  • Rows 1, 2, 3, 4, 5, 6, 7

Items

  • Rows 1, 2, 3, 4, 5, 6, 7, 8, 9

Data persisted on device

BusinessPartners

  • Rows 1, 2, 3

SalesOrders

  • Rows 1, 2, 3, 4, 5, 6, 7

Items

  • Rows 1, 2, 3, 4, 5, 6, 7, 8, 9

Products

  • Rows 1, 2, 3, 4

ProductDetails

  • Rows 1, 2, 3, 4

Request 2

SalesOrders

  • Rows 3

Items

  • Rows 4, 5

Request 3

Products

  • Rows 1, 2, 3, 4

ProductDetails

  • Rows 1, 2, 3, 4

SMP Server queries the backend using the defining requests.  The union of the data retrieved by all the defining requests is used to populate the database on the SMP Server.  This prepopulated database is then sent to the device.  Note that data is not duplicated on the device – just the union of the data retrieved by all the defining requests is persisted.  For efficiency reasons, it is recommended not to have overlapping defining requests.  However, even if you have overlapping defining requests, data will not be duplicated on the device.

Lot less happens during subsequent openings of the Offline Store.  The application does not connect to SMP Server.  Therefore application does not require network connection. Application simply opens the existing database on the device.

Store

Action

Offline Store (first time opening)

Needs network connection

Defining request sent to SMP Server

SMP Server queries backend using defining requests

Creates a new database with backend response

Sends newly created database to device

Offline Store (Subsequent openings)

Does not need network connection

Simply opens existing database on device

Does not connect to SMP Server

How do I create and open an Offline Store?

Creating an Offline Store is straightforward.  The constructor does not take any parameters.

this.Store = new SAP.Data.OData.Offline.Store.ODataOfflineStore();

Opening the Offline Store takes ODataOfflineStoreOptions as a parameter

await this.Store.OpenAsync(options);

So, how do I create this “options” parameter?  For this, you need to create the ODataOfflineStoreOptions object with the proper values. Thankfully, most values are intuitive. The following code snippet creates the ODataOfflineStoreOptions and populates it with the proper values.

var options = new SAP.Data.OData.Offline.Store.ODataOfflineStoreOptions();

var client = new SAP.Net.Http.HttpClient(new System.Net.Http.HttpClientHandler()

   {Credentials = new System.Net.NetworkCredential(“user”, “password”)},

   true); // will be disposed by the store!

client.DefaultRequestHeaders.TryAddWithoutValidation("X-SMP-APPCID", connectionId);

client.DefaultRequestHeaders.TryAddWithoutValidation("X-SUP-APPCID", connectionId);

client.ShouldHandleXcsrfToken = true;

options.ConversationManager = client;

options.Host = "10.4.64.212";

options.Port = 8080;

options.ServiceRoot = "com.sap.flight";

options.EnableHttps = false;

options.StoreName = "OfflineStore";

options.StoreEncryptionKey = "SuperSecretEncryptionKey";

options.URLSuffix = "";

options.AddDefiningRequest("TravelagencyDR""TravelagencyCollection"false);

options.EnableRepeatableRequests = true;

Note:  For operations that change state (for example, inserting a new resource) re-issuing the request may result in an undesired state (for example, two orders placed).  Set EnableRepeatableRequests property to true to avoid such situations.  Note that the backend OData Service must support this feature.  SAP Gateway supports this feature. 

CRUD operations on Offline Store after opening

CRUD operations can be performed on the Offline Store after successfully opening the Offline Store. The syntax for CRUD operations on an Offline Store is identical to the syntax for an Online Store.  The only difference is that the data is retrieved from the locally persisted ultralite database instead of from the backend.

CREATE


var execution = store.ScheduleCreateEntity(entity, collectionName);

var response = await execution.Response;

READ


var execution = store.ScheduleReadEntitySet(collectionName);

var response = await execution.Response;

UPDATE



var execution = store.ScheduleUpdateEntity(copiedEntity);

var response = await execution.Response;

DELETE


var execution = store.ScheduleDeleteEntity(entity);

var response = await execution.Response;

Understanding Flush and Refresh

Flush and refresh allows the locally persisted data to be synchronized with the backend data.  Both Flush and Refresh methods require network connection.  Flush allows changes made locally on the device to be applied on the backend in an asynchronous fashion.  Refresh on the other hand, allows changes made on the backend to be downloaded to the device.  An important thing to note when calling the Flush method is that all the changes made locally on the device are submitted.   The SDK currently does not support sending part of the changes.  However, Refresh method has the option of downloading part of the backend changes based on defining request.

Flush method

Refresh method

Requires network connection

Requires network connection

Changes made locally submitted to backend

Changes made on backend downloaded to device

This call is asynchronous

This call is asynchronous

All changes are submitted – Cannot submit part of the changes

Developer has the option of downloading part of backend changes based on defining request

Call Flush before calling Refresh

Call Flush before calling Refresh

FLUSH


await this.Store.ScheduleFlushQueuedRequestsAsync();

REFRESH

await this.Store.ScheduleRefreshAsync(); OR

await this.Store.ScheduleRefreshAsync(definingrequest);

Some important considerations

  • Offline support for Windows is only available for Windows Store applications and Windows Phone Store applications.  Offline support is not available for Windows desktop .NET applications.
  • The local database is created in the location given by: Windows.Storage.ApplicationData.Current.LocalFolder.  It is essentially the application data directory.  iLoData.exe is an utility that is shipped with SMP SDK SP11 onwards.  This command line utility can be used to open the local ultralite database and view the contents.  This is a great tool for troubleshooting purposes.
  • The Offline Store takes care of getting and setting the XCSRF token in the MobiLink server component.  Nothing additional needs to be done on the client application.
  • Batch processing is supported in the Offline Store as well.
  • In the event, the SMP Server is configured with multiple endpoints, then your application can have multiple Offline Stores (one for each endpoint – make sure you supply a unique store name for each Offline Store).  You can also have multiple Offline Stores open at the same time.
  • You can also have Online Store and Offline Store (for the same endpoint) in the same application.  Both these stores can be open at the same time.  Depending on network availability, the developer can choose which store to use. A lot of times it is easier to only have the Offline Store and use it regardless of network connectivity. Periodically call flush and refresh to sync the data with the backend.

Please feel free to post any comments or questions that you might have.  I will try to answer them as soon as I can.  Hopefully, these blogs have given you enough insights into the Windows SDK to start building new mobile applications.  Good luck !

33 Comments