I am currently working on my next Pluralsight course about SAP Business Warehouse, SAP Mobile Platform and Xamarin integration and I am refactoring my example ProjectRanker app so that it can use OData with JSON for getting the information from the server. This post is about the introduction of the Xamarin SAP SDK component and it's important Caching functionality.
Xamarin and SAP SDK
When Xamarin and SAP announced their partnership, a new component was born, called SAP SDK. SAP SDK is an OData client written in C# as a Xamarin Component and facilitates the communication between the SAP Mobile Platform server and the mobile device, like the authentication process, accessing and working enterprise data, asynchronous communication, or caching and parsing the messages. I have already tried SAP SDK for my sample ProjectRanker app and it worked quiet well, but the caching was not obvious for me for the first time, so I decided to clarify this mechanism for you.
Importance of Caching
Any kind of document format and technique you choose, you need to think about caching your data to keep your app well performant and responsive. If we work with enterprise data, we need to balance the communication between the server and the client. Caching is a great mechanism to save a part of the database on the client side so that we can reduce the communication efforts to the necessary minimum level. For mobile devices, it's even more important because internet is not always fast and not always available, so we need to prepare our app for the situation that we are not available to send new data to the SAP server. Caching helps also to keep the data for avoiding such a data loss.
SAP SDK Cache Components
SAP SDK uses caching of the OData requests by default, we don't need any additional configuration in order to use this feature. We can send OData requests to the server through the SAPClient class. This class handles all of the requests and stores the received results in an encrypted SQLite database on the mobile device. The SAPClient decides based on its Cache Mode how to serve the requests, from the server or from the local device cache. The generation, handling or deleting old records from the SQLite cache database is automated by the client.
In order to achieve this caching mechanism, SAP SDK implements the following components:
- Cache Store
- Cache Item
- Cache Mode
- Cache Policy
Let's see the role of these components.
Cache Store with ICacheStore
The cache store is a cache database that can work with a list of cache items. The cache store is responsible for saving, reading or deleting cached entries. The contract for this database is defined in the ICacheStore interface and currently SAP SDK implements this interface with class SQLiteCache that can achieve this functionality on a local SQLite database.
Cache Item with ICacheItem
We can consider a Cache Item as a record in the cache database. It stores a request received from the SAP Mobile Platform server. It has the following fields:
- Content: the data received in JSON format from the server
- Uri: we can get or send data with OData requests through parameterized URL's. This URL is needed for checking if we sent such a request before.
- OperationMethod: This is an enumeration, with the entries like Create, Read, Update, Delete. The operation method is also needed for identifying the requests.
- SizeInBytes, LastUpdated: these are additional information about the entry and are used to invalidate and delete the cache entry based on its Age or on its Size. The client regularly purges old or big requests from the cache database, so the data is always as fresh as possible in the cache.
The SQLiteCacheItem class implements this interface and it's a simple Data Transfer Object that defines the structure of the SQLite database.
The SAPClient supports different cache modes. I would like to highlight that these modes have not any effect on the SQLite storage. The SAPClient class always creates a cache entry in the SQLite database. We cannot switch off the SQLite database using these modes.
The Cache Mode defines how a particular OData request is served, from the SQLite cache or from the server, using the network and in which order. Like that, there are 4 different scenarios:
- OfflineOnly: All the requests to the client are served fro the SQLite cache database. This option is useful when the device is switched to AirPlane Mode but we would like to work with the data. If there is no entry for a request, an error occures.
- OnlineOnly: All the requests are served from the server. In this mode, the requests are still cached in the SQLite database, like that we can switch between the cache modes later, we are going to have data in the cache.
- OfflineBeforeOnline: The client tries first to serve the request from the SQLite database and if it's not possible then it sends the request to the server. This mode is good for performance improvement of new requests: the server will get the data from the server, but next time the client can work with the SQLite local database.
- OnlineBeforOffline: This mode is similar to the previous one, but the priority order is first the server. If the can't get the data through the network, then it tries to get it from the local cache.
Cache Policy with ICachePolicy
Caching data is very good for balancing the resources, but there is always a problem how to keep the database on the server and the local cache in sync. The ICachePolicy interface has an Execute method with a CacheStore parameter. The Cache policy's Execute method is always called before serving a request and it's responsible for deleting records from the local cache corresponding to a specific rule. The Cache Policy is beneficial for defining rules for the syncing. SAP SDK has 2 default implementations:
- AgedCachePolicy: this policy checks the age of a record, if it's too old, it deletes this record.
- StorageCachePolicy: this policy checks the total size of the cache database and compares it with a size limit. If the size of the cache database is greater than the limit, than this policy deletes the cache entries starting with the oldest entry.
As you could see in my post that SAP SDK has implemented the SAPClient with different interfaces, so there might be many extension points for custom implementations. Unfortunately it's not like that because there are not much open doors for using Dependency Injection, we can only extend the Cache Policy and create a custom rule.
We can inject a custom Cache Policy through the SAPClient class's AddCachePolicy method.
I hope, I could highlight some details about the cache behavior of the SAP's OData client. If you are curious about more details of the SAP SDK and SAP Mobile Platform, check out my coming course on Pluralsight: Building Native Mobile Apps for SAP Business Warehouse - Part 2.