3 iOS Applications

If you are an iOS app developer, you can use the client SDK that Oracle Mobile Cloud Enterprise (OMCe) provides for iOS. This SDK simplifies authentication with OMCe and provides Objective-C wrapper classes for OMCe platform APIs.

Getting the SDK

To get the OMCe client SDK for iOS, go to the Oracle Mobile Cloud Enterprise Downloads page on OTN.

Creating a Backend

You create a backend to serve as a secure gateway between your app and OMCe features, such as platform and custom APIs. For your app to access these resources, it authenticates with a backend.

  1. Click icon to open the side menu to open the side menu and select Mobile Apps > Backends.

  2. Click New Backend.

  3. Once you complete the dialog and the backend is created, keep the Settings page open.

    You’ll need to configure your app with some of this information.

Adding the SDK

Assuming a basic app setup, without intervening frameworks, here’s what you would do to add the iOS client SDK to an app.

  1. Unzip the download file, omce-ios-sdk-{n}.zip (where {n} is the version number of the SDK) into some directory on your machine.

  2. From the extracted contents of the zip, drag and drop the oracle_mobile_ios_sdk directory to the Xcode project navigator.

    • Select Copy items if needed.

    • Select Create Groups.

    • Click Finish.

    Once the .a file for a specific library has been copied into your application’s development tree in Xcode, the corresponding platform API is available to your app through SDK calls. At this point, all of the SDK’s static libraries are available to your app.

  3. Select the target for your project, select the Build Phases tab, expand Link Binary with Libraries, click the + button, and add the following libraries:

    • CoreData.framework

    • CoreLocation.framework

    • libsqlite3.0.tbd

    • Security.framework

    • SystemConfiguration.framework

  4. In the Build Settings section for the project, double-click Other Linker Flags (under Linking) and add -ObjC.

  5. Also in Build Settings, expand Search Paths and:

    1. Add oracle_mobile_ios_sdk/release-iphoneos to Library Search Paths.

    2. Add oracle_mobile_ios_sdk/release-iphoneos/include to User Header Search Paths.

  6. Expand the Documentation folder of the unpacked zip, copy the OMC.plist file, and place it in the root of your app’s main application bundle.

  7. Edit the just-copied OMC.plist file. See Configuring SDK Properties.

  8. Starting with Xcode 7, you need to account for the Application Transport Security (ATS) policy, which enforces remote communications to be over HTTPS.

    For development purposes only, add the following key in app’s Info.plist file to turn off the ATS policy for the app.

    <key>NSAppTransportSecurity</key> 
    <dict>
     <key>NSAllowsArbitraryLoads</key>
     <true/> 
    </dict>

    Note:

    You shouldn't use this setting in production. To make sure you provide optimal security for your app, study Apple's documentation for NSAppTransportSecurity and follow Apple's recommendations for disabling ATS for specific domains and applying proper security reductions for those domains.

Configuring SDK Properties

To use the client SDK in an iOS app, you need to add the OMC.plist configuration file to the app and fill it in with environment details for your backend in OMCe, as well as other configuration information. In turn, the SDK classes use this information to help manage authorization, logging, event tracking, data synchronization, and other features.

You package the configuration file in the root of your app’s main bundle.

The file is essentially divided into the following parts:

  • The mobileBackend key and its contents.

    You include this part if you are using a backend with the app. The SDK classes use the environment and authentication details you specify there to access the backend and construct HTTP headers for REST calls made to APIs.

  • Keys that apply to the configuration as a whole, such as logLevel and oAuthTokenEndpoint. These keys generally, but don’t have to, appear at the top of the file.

Here’s the same file in text form:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"
<plist version="1.0">
<dict>
  <key>logLevel</key>
  <string>debug</string>
  <key>logHTTP</key>
  <true/>
  <key>oAuthTokenEndPoint</key>
  <string>https://MY_TOKEN_ENDPOINT</string>
  <key>mobileBackend</key>
  <dict>
    <key>name</key>
    <string>EasyShoppingMBE</string>
    <key>baseURL</key>
    <string>https://MY_CLOUD_DOMAIN.oracle.com</string>
    <key>authentication</key>
    <dict>
      <key>type</key>
      <string>oauth</string>
      <key>oauth</key>
      <dict>
        <key>clientID</key>
        <string>11dac238ffaa4b029e78e982114642ab</string>
        <key>clientSecret</key>
        <string>5624cbdd-a7c5-4c10-a758-6019a5ab8da8</string>
        <key>enableOffline</key>
        <true/>
      </dict>
    </dict>
  </dict>
</dict>
</plist>

And here is a description of some of the more important entries in the OMC.plist file.

  • oAuthTokenEndPoint — The URL of the OAuth server from where your application gets its authentication token. This key needs to be provided for all apps that rely on OAuth to authenticate. You get this from the backend’s Settings page. The endpoint should be only the base URL (in the form https://host.domain:port).

  • logLevel — Determines how much SDK logging is displayed in the app’s console. The default value is error. Other possible values (in increasing level of detail) are warning, info, and debug. It is also possible to set the value to none.

  • logHTTP — When set to true, the SDK logs the headers and bodies of all HTTP requests and responses.

  • mobileBackend — A dictionary entry containing authentication details for your backend and other optional details, such as synchronization properties.

    You get the authentication details, such as the OAuth and HTTP credentials, from the backend’s Settings page.

  • mobileBackend/baseUrl — The base URL for all APIs that you call through the backend. You get this from the backend’s Settings page.

  • mobileBackend/authentication — Contains a dictionary with the following elements:

    • The type sub-key, with possible (string) values of oauth, basic, facebook, and tokenExchange.

    • One or more sub-keys for authentication types, containing a dictionary with the authentication credentials.

      Within sub-keys for basic and oauth, you can also add the enableOffline key. By default, this property is set to true.

    See Authentication Properties for examples of each authentication type.

Authentication Properties

The contents and sub-elements of the mobileBackend/authentication key depend on what kind of authentication the app will be using.

OAuth
  • Set the value of the type key to oauth.

  • Create an oauth sub-key and fill in the clientID and clientSecret  credentials provided by the backend.

  • At the top level of the file, supply the oAuthTokenEndPoint value that is supplied but without the oauth2/v1/token that is appended on the backend’s Settings page.

  • Optionally, if you want to disable offline authentication, add the enableOffline sub-key and set it to false.

The resulting authorization property might look something like this:

<key>authentication</key>
<dict>
  <key>type</key>
  <string>oauth</string>
  <key>oauth</key>
  <dict>
    <key>clientID</key>
    <string>11dac238ffaa4b029e78e982114642ab</string>
    <key>clientSecret</key>
    <string>5624cbdd-a7c5-4c10-a758-6019a5ab8da8</string>
  </dict>
  <key>basic</key>
</dict>
HTTP Basic
  • Set the value of the type key to basic.

  • Create a basic sub-key and fill in the HTTP Basic credentials (mobileBackendID and anonymousKey) provided by the backend.

  • Optionally, if you want to disable offline authentication, add the enableOffline sub-key and set it to false.

The resulting authentication entry might look something like this:

<key>authentication</key>
<dict>
  <key>type</key>
  <string>basic</string>
  <key>basic</key>
  <dict>
    <key>mobileBackendID</key>
    <string>a8c6a34f-61bb-4bee-948c-d43dd2c077d7</string>
    <key>anonymousKey</key>
    <string>dXNlcmlkOnBhc3N3b3Jk</string>
  </dict>
</dict>
Token Exchange

If you are authenticating using a third-party token, do the following:

  • Set the value of the type key to tokenExchange.

  • Create a tokenExchange sub-key and fill in the OAuth Consumer credentials provided by the backend.

The resulting authentication section might look something like this:

<key>authentication</key>
<dict>
  <key>type</key>
  <string>tokenExchange</string>
  <key>tokenExchange</key>
  <dict>
    <key>oauth</key>
    <dict>
      <key>clientID</key>
      <string>b39ba08d30d54e24970332fcdffec3a7</string>
      <key>clientSecret</key>
      <string>23953fe8-76ed-4c89-a5cb-6042db10cfaf</string>
    </dict>
    <key>basic</key>
    <dict>
      <key>mobileBackendID</key>
      <string>8d3744b8-cab2-479c-998b-ebba2c31560f</string>
      <key>anonymousKey</key>
      <string>ZFJJTUVfREVDRVBUSUNPTl9NT0JJTEVfQU5PTll</string>
    </dict>
  </dict>
</dict>

Calling Mobile APIs

In OMCe, a backend is a logical grouping of custom APIs, storage collections, and other resources that you can use in your apps. The backend also provides the security context for accessing those resources.

Here are the general steps for using a backend in your iOS app:

  1. Add the client SDK to your app.

  2. Fill in the OMC.plist with environment and authentication details for the backend.

  3. Add an SDK call to your app to load the configuration info.

  4. Add an SDK call to your app to handle authentication.

  5. Add any other SDK calls that you want to use.

Loading the Backend's Configuration

For any calls to OMCe APIs using the iOS client SDK to successfully complete, you need to have the mobile backend’s configuration loaded from the app’s OMC.plist file. You do this using the OMCMobileBackend class:

/**
 * Returns the mobile backend that is configured in OMC.plist file
 */
OMCMobileBackend* mbe = [[OMCMobileManager sharedManager] mobileBackend];

Authenticating and Logging In

Here is some sample code that you can use for authentication through OMCe in your iOS apps. Each sample is based on the OMCAuthorization.h class and relies on the following imports:

#import "OMCCore/OMCAuthorization.h"
#import "OMCCore/OMCMobileBackend.h"
#import "OMCCore/OMCMobileManager.h"

OAuth Consumer and HTTP Basic

You can use the following method to handle a user logging in with a user name and password:

- (void) authenticate:(NSString *)userName
             password:(NSString *)password
      completionBlock: (nullable OMCErrorCompletionBlock) completionBlock;

This method terminates the connection to OMCe and clears the user name and password from the iOS keychain:

-(void) logout: (nullable OMCErrorCompletionBlock) completionBlock;

SSO with a Third-Party Token

First, your app needs to get a token from the third-party token issuer. The way you can obtain the token varies by issuer. For detailed information on obtaining third-party tokens and configuring identity providers in OMCe, see Third-Party SAML and JWT Tokens.

Once you have the token, use it to authenticate. The code in this example checks to seeif the token is already stored in OMCe before logging in again:

-(void) authenticateSSOTokenExchange: (NSString*) token
                    storeAccessToken:(BOOL) storeToken
                     completionBlock: (OMCErrorCompletionBlock) completionBlock;

Note:

The default expiration time for storing a third-party token in OMCe is 6 hours. You can adjust this time by changing the Security_TokenExchangeTimeoutSecs policy. See Modifying Policies in Administering Oracle Mobile Cloud, Enterprise.

SSO with a Third-Party Token — Staying Logged In

You can also code the app to keep the user logged in, even when closing and restarting the app.

In the authenticateSSOTokenExchange method, if storeAccessToken is set to YES, the token is stored in secure store and the user remains logged in until the token expires.

You can use the loadSSOTokenExchange() method in the app launch sequence to load the token from the keychain. (If a token can’t be retrieved, the method returns NO).

Here’s some code that tries to load a saved token and, if it fails, restarts the authentication process:

OMCAuthorization* auth;
if ( [auth loadSSOTokenExchange] ){
	NSLog(@"## Token already found, login skipped.");
    ...
}
else{
	[auth authenticateSSOTokenExchange:thirdPartyToken
				  storeAccessToken:YES
				   completionBlock:^(NSError * _Nullable error) {
					   
					   if( error ){
						   //Show error popup
					   }
					   else{
							// Login success.
							...
					   }
				   }];
}

When you have the token stored in the secure store, it remains associated with the backend that the app originally used. Therefore, if the app is updated to use a different mobile backend (or mobile backend version), you need to clear the saved token (using clearSSOTokenExchange) and re-authenticate.

Calling Platform APIs

Once the backend’s configuration info is loaded into the app, you can make calls to client SDK classes based on the iOS Core library classes.

The iOS Core library (libOMCCore.a) provides the following key interfaces:

  • OMCMobileManager

  • OMCMobileBackend (a sub-class of OMCMobileComponent)

  • OMCServiceProxy

The root object in the SDK is the OMCMobileManager. The OMCMobileManager manages the OMCMobileBackend objects.

The OMCMobileBackend object is used to manage connectivity, authentication, and other transactions between your application and its associated mobile backend, including calls to platform APIs and any custom APIs you have defined. It manages calls to platform APIs via subclasses of OMCServiceProxy such as OMCLocation and OMCStorage.

Here’s an example of using SDK classes to call the Storage API:

#import "OMCMobileBackend.h"
#import "OMCMobileManager.h"
#import "OMCAuthorization.h"
#import "OMCStorage.h"
#import "OMCMobileBackend+OMC_Storage.h"
#import "OMCSynchronization.h"

- (NSData*)dataFromStorageObjectWithID:(NSString*)objectID collectionID:(NSString*)collectionID {     

  // Get mobile backend
  OMCMobileBackend* mbe = [[OMCMobileManager sharedManager] mobileBackend];

  // Get storage object
  OMCStorage* storage = [mbe storage];
    
  // Get your collection
  OMCStorageCollection* collection = [storage getCollection:collectionID];
    
  // Get your object from your collection
  OMCStorageObject* object = [collection get:objectID];
    
  // Get the data from payload of your object
  NSData* data = [object getPayloadData];

   return data; }

}

Note:

Methods written in Objective-C that are used in the OMCe SDK for iOS can also be mapped to Swift. For more information, see Writing Swift Applications Using the iOS Client SDK.

Calling Custom APIs

The client SDK provides the OMCCustomCodeClient class to simplify the calling of custom APIs in OMCe.

Using this class, you invoke a REST method (GET, PUT, POST, or DELETE) on an endpoint where the request payload is JSON or empty and the response payload is JSON or empty.

In addition you can provide a completion handler to be called when the request invocation is complete (meaning that the handler runs asynchronously).

If the completion handler is set, it will be invoked in the UI (main) thread upon completion of the method invocation, allowing update of UI items. The completion block will contain the format-specific data for a JSON object, namely an NSDictionary or NSArray. Use the completion block for any returned data or errors, HTTP or system.

All of the required OMCe headers, such as Authorization (assuming the user has authenticated), will automatically be inserted into the request.

Use of OMCCustomCodeClient might look something like this:

#import "OMCCore/OMCMobileBackend.h"
#import "OMCCore/OMCCustomCodeClient.h"
...
 
// A GET, PUT, POST, or DELETE method may be specified here - sent or returned JSON data object may be nil as appropriate.
OMCMobileBackend *backend = [[OMCMobileManager sharedManager] mobileBackend];
OMCCustomCodeClient *ccClient = backend.customCodeClient;
NSDictionary *jsonPayload = @{@"myKey": @"myValue"};
[ccClient invokeCustomRequest: @"API2/endpoint2" 
                       method: "@PUT" 
                         data: jsonPayload, 
                   completion: ^(NSError* error,
                                NSHTTPURLResponse *response,
                                id responseData) {
        // error will be nil if no problems occurred, otherwise it will contain the error object
        // response will be complete HTTP response
        // response data will be Map or Array for JSON object if success or nil if error
    }];

Libraries and Dependencies

Libraries

The iOS client SDK contains the following items:

  • Documentation - Contains web-browser based documentation (html.zip) and a docset for browsing and accessing context-sensitive help from Xcode (oracle.mobile.cloud.Oracle-Mobile-Cloud-Enterprise-iOS-SDK.docset.zip). To use html.zip, unzip the file and browse the main page from index.html. To use the docset, unzip the file into the usual location for Xcode docsets, typically something like ~/Library/Developer/Shared/Documentation/DocSets, where ~ is your home directory.

    This folder also contains a sample copy of the OMC.plist file that you’ll need to add to your app and populate with the configuration details for your mobile backend.

  • oracle_mobile_ios_sdk/release-iphoneos - Release versions of the static libraries and header files. Also contains SyncStore initialization data. The static libraries are Universal (fat) binaries that contain armv7* code and support both the iPhone Simulator and real devices. The following static libraries are included:

    • libOMCCore.a - The Core static library file shared by all iOS applications. Contains the common libraries required by all other libraries.

    • libOMCAnalytics.a - The Analytics library, which lets you insert custom events into your code that can then be collected and analyzed from the Analytics console. This library has been deprecated.

    • libOMCLocation.a - The Location library, which lets you access details about location devices that have been registered in OMCe and the places and assets they are associated with.

    • libOMCNotifications.a - The Notifications static library file, which allows you to set up your application to receive notifications sent from your mobile backend.

    • libOMCStorage.a - The Storage static library file, which allows you to write code to access storage collections that are set up with your mobile backend.

    • libOMCSynchronization.a - The Data Offline static library file, which allows you to cache application data when the device running your app is disconnected from the network, then synchronize the data when the network connection is reestablished.

Dependencies

The client SDK is modular, so you can package just the libraries that your app needs. Just be aware of the following dependencies:

  • Every app must have the libOMCCore.a static library file.

  • If your app uses libOMCStorage.a, you must also include lilbOMCSynchronization.a.

  • If your app uses lilbOMCSynchronization.a, you must also include the SyncStore.momd folder, which contains initialization data.

Next Steps

Once you have the iOS SDK set up, you can start using it to add OMCe features to your app.