Skip to Content

With the latest SAP Cloud Platform SDK for iOS Assistant you can create a ready to run Xcode project for iPhone/iPad within couple of minutes. that application can be accessible when you got internet connectivity in your phone either connected to wi-fi or 3G/4G or so.

Think about enabling same app being accessible irrespective of whether you have internet connectivity or not. Then now questions are:

How to make this app offline enabled?

Do i need to write any piece of code ? If yes, then where and what?

How will i take care of app flow when app goes in background and want to bring it back in foreground?

How will i take care of app flow if i accidentally kill app from background and relaunch it?

There could be so many questions like above.

To answer these, yes, you need to write some piece of code to enable app for offline usage. The latest addition of framework (SAPFioriFlows) will take care of app on-boarding and restoring process.

In this blog post, i will share some information that could help you with above mentioned questions however post will not cover all offline possible use cases:

 

Tools used: XCode 9.2 , iOS simulator 11.2, SAP Cloud Platform SDK for iOS 2.0 PL03

Lets get started with iOS SDK Assistant app, create a simple master detail app by following below highlighted steps (1-6)

App Name: DemoApp

appID: com.sap.demo

For OData destination, add a new destination,

URL: https://hcpms-<SCNID>trial.hanatrial.ondemand.com/SampleServices/ESPM.svc

Proxy Type: Internet

Authentication: Single Sign On

 

this is how Xcode project structure looks like,

Onboarding flow (in Onboarding), ViewController class for master & detail for each collections and respective storyboard (under ViewControllers), generated ProxyClasses for all the collections for given OData Endpoint

 

Running the project on a simulator leads to an online master detail app , it was very easy, right?

 

 

I wont be able to access app data if i dont have internet connectivity in my device since app is not yet offline enabled.  What if i want to have only “SalesOrderHeaders” collection as offline enabled?

 

How to do that? What piece of code i have to write in which swift file?

For doing this, we need to understand “OfflineOData” concept. In SAP Cloud Platform SDK for iOS, we have SAPOfflineOData framework, which retrieves back-end OData services when the app is online, then creates an offline OData store which is initialised and populated with a list of defining queries. The store is persisted on the device. Device users manipulate the local data (create, update, delete. query and so on ), then later upload the offline changes to back-end via SAP Cloud Platform Mobile Services for Development & Operations. SAPOfflineOData also provides additional functionalities.

In 2.0 release, the handling of the DataService has been moved into the AppDelegate’s ConfigureOData function.

(Make sure to create GIT repositories before making any changes to your project, will help you to track changes, restore project to a previous state and so on)

 

 

make/add below code in some of existing swift files:

AppDelegate.swift

  • Import declaration of  SAP OfflineOData
import SAPOfflineOData

 

  •   Creating an offline OData provider for data service declaration to Offline
     var offlineStore: ESPMContainer<OfflineODataProvider>!​

  • Define below field isOfflineStoreOpened (this field holds the state of the store, if it’s open or not)

 

  private var isOfflineStoreOpened = false

  • scroll down and look for ConfigureOData function, add below code for defining request for offline and open the offline store before last two brackets
    • /// defining Request for offline
              /// initialise the OfflineODataParameters
              var offlineParameters = OfflineODataParameters()
              offlineParameters.customHeaders = ["X-SMP-APPID": "com.sap.demo"]
              let offlineODataProvider = try! OfflineODataProvider(serviceRoot: URL(string: serviceRoot.absoluteString)!, parameters: offlineParameters, sapURLSession: urlSession)
              /// define the initial set of Data, the AppID and the Offline OData Provider for the store
              try! offlineODataProvider.add(definingQuery: OfflineODataDefiningQuery(name: CollectionType.salesOrderHeaders.rawValue, query: "/\(CollectionType.salesOrderHeaders.rawValue)", automaticallyRetrievesStreams: false))
            
              offlineStore = ESPMContainer(provider: offlineODataProvider)
              
              openOfflineStore{ result in }
              
          }
          
          /// opens the offline store. if store does not exists it will trigger the initial download of the store and create the local DB
          /// - Returns: returns the status
          
          private func openOfflineStore(completionHandler: @escaping (String) -> Void) {
              guard !isOfflineStoreOpened else {
                  completionHandler("Offline store opened.")
                  return
              }
              ///  The OfflineODataProvider needs to be opened before performing any operations.
              
              offlineStore.open { error in
                  if let error = error {
                      completionHandler("Could not open offline store \(error.localizedDescription)")
                      return
                  }
                  self.isOfflineStoreOpened = true
                  completionHandler("Offline store opened.")
              }
    • OfflineODataProvider: A data service provider for Offline OData.
    • OfflineODataParameters contains the configuration details required to open an OfflineODataProvider.
    • Custom headers to add to all HTTP communications. These are added to HTTP requests between the OfflineODataProvider and server and to HTTP requests between the server and the OData backend. The keys are header names. The values are header values.
    • OfflineODataDefiningQuery: A defining query is an OData read request that targets the OData backend associated with the OfflineODataProvider and retrieves a subset of the OData backend data. Multiple defining queries can be defined for each OData backend. Defining queries are a subset of data from the OData backend that is sent to the client either during the initial open of the OfflineODataProvider or during a download.
    • openOfflineStore:opens the offline store. if store does not exists it will trigger the initial download of the store and create the local DB

SalesOrderHeadersMasterViewController.swift

look for SalesOrderHeaders collection view controller, open its master swift file

  • Import SAP OfflineOData declaration
    import SAPOfflineOData​
  • Add below code in SalesOrderHeaderMasterViewController class
    private var offlineStore: ESPMContainer<OfflineODataProvider>{
    	        return self.appDelegate.offlineStore
        }​

 

  • scroll down and look for requestEntities function, change self.espmContainer to self.offlineStore 

ConfigurationProvider.swift

The SAPFioriFlows framework includes components that combine existing SAPFoundation, SAPCommon and SAPFiori capabilities into a higher level framework that allows you to develop complex onboarding processes using just a few lines of code. SAPFioriFlows supports most typical application onboarding scenarios.

SAPFioriFlows uses SAPFoundation’s ConfigurationProvider component to gather required configuration information.

Since we have generated project using Assistant, we already got on-boarding process implemented in OnboardingManager class.

You can find it under Onboarding folder. Look for restoringSteps in OnboardingManager class and comment below field

self.configuredOAuth2AuthenticationStep(),
SAPcpmsSettingsDownloadStep(),

 

OAuth2AuthenticationStep: OAuth2.0 onboarding step used in restoring flow, it is responsible to configure the app’s URLSession to be able to communicate with OAuth 2.0 protected resources.

SAPcpmsSettingsDownloadStep : Class for SAPcpmsSettings download on-boarding step handling

Note:

    ** For a pure Online App , you dont need to comment above , it will help you in downloading latest or updated on-boarding steps

** Commenting above two lines will basically restore app from a persisted state. Read here for more on-boarding flow

       ** With help of Reachability API from Apple, you can monitor the network state of an iOS device to adjust to your need.

reinstall the app on simulator, follow same on-boarding steps, as soon as collections details show up, offline store is initialised and populated with mentioned defining queries (only for SalesOrderHeaders)

 

(I used simsim application to access simulators’ apps file directory)

 

as expected i cant access Customers collection data (when i dont have internet connectivity) but can access SalesOrderHeaders (since i have explicitly chosen SalesOrderHeaders collection data as offline enabled)

If i put my app in background and bring it in foreground or kill the app from background and relaunch, i should be able to access same data.

Check below resources for more information:

Help Documentation

What’s new in SAP Cloud Platform SDK for iOS 2.0

SAP Translation Integration – SAP Cloud Platform SDK for iOS 2.0

SAP API Business Hub Integration – SAP Cloud Platform SDK for iOS 2.0

From API to App: Assistant tool generates mobile app scaffolding from a Backend API

I hope this will help you.

Regards.

Jitendra Kansal

Product Management, SAP Cloud Platform User Experience
SAP SE

 

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

Leave a Reply