Subaio Fintech Bridge for iOS

This document provides informations of how to use the Subaio Fintech Bridge in your projects. There exists 3 Fintech Bridge libraries;

  • Fintech Bridge for iOS
  • Fintech Bridge for Android
  • Fintech Bridge for Web.

The libraries provides user interfaces, API integrations and other functionality related to Subaio. The purpose of the libraries is to reduce the implementation and maintenance cost the host applications, while enabling the Subaio application to evolve parallel with the host application. While there are slight differences between them because of differences in syntax and convention, the general structure is the same.

Architecture

The fintech bridge is intended for embedding small, widget-like applications inside a larger app. The application is structured in the following parts:

  • Host application: The iOS-, Android-, or web-application that hosts the Subaio components. This might be a mobile bank application or web home banking solution.
  • Bridge: The bridge library is used by the host application to grant easy control over the embedded app as well as a standardized event system. It consists primarily of two components:
    • SubaioManager: A singleton-class for global configuration of all subaio-views, authentication mangagement, as well as communication between views.
    • SubaioView: A wrapper around a single embedded application.
  • Embedded application: The Subaio web-application running inside of a webview/iframe.

Including embedded applications thus requires including the bridge library, configuring the SubaioManager and instantiating a SubaioView.

Each bridge project includes an example project demonstrating how to use the manager and the views.

To better facilitate native transitions between pages, the subaio app is separated in pages that can be placed in separate view-controllers and pushed separately to the nagivation stack.

Each instance of an embedded view can be set to show a specific Page, defined by a name and optionally a set of parameters, e.g. Page(name: "OVERVIEW", params: nil) or Page(name: "SUBSCRIPTION", params: ["subscriptionId": "..."]). The exact pages will depend on the application. For simple integrations where the views are simply pushed to the navigation stack, the host application only need knowledge of the initial overview page, available as Page.overview for convenience.

Views will push new pages using the navigatedTo event.

Notifications for the embedded app should generally be implemented to pass name and params provided by subaio on to the host application to easily handle navigation. See the Push Notifications section for details.

Authentication

The subaio views use JSON web tokens for authentication. All views use a shared token, administred by the SubaioManager. The tokens generally expire after one hour, so the SubaioManager has internal logic to automatically refresh the token when necessary.

The preferred method of obtaining a subaio token is to let the host application make an authenticated request to its own backend, which will then request a token from the subaio backend.

The host application is responsible for providing a callback for obtaining a token to the SubaioManager. This callback must handle three cases:

  • Successfully obtained a token. This is distributed to the views and used for future requests.
  • Temporarily unavailable, from a network outage or similar. The SubaioManager will ignore this attempt and try to request a new token later (likely after 1 minute).
  • User unauthenticated. The user is no longer logged in and any active views should be cleared of all data. The SubaioManager will stop requesting new tokens.

Besides providing the callback, the host application should invoke SubaioManager.shared.refreshToken when the current user is unauthenticated or a new user is authenticated.

See TokenRequiredCallback.

Configuring the SubaioManager

The following options needs to be provided to the SubaioManger before any views can be instantiated:

  • baseUrl: The URL where the embedded app is hosted.
  • allowExternalUrls: (default false) Allow the embedded app to open arbitrary URLs on the phone. This is primarily used to help navigate the user to iTunes/Google Play subscription pages. This needs to be enabled for the embedded app to be fully functional.
  • allowShare: (default false) Allow the embedded app to request a share dialog to share a message. This is primarily used to help the user help others to find their iTunes subscription page. This needs to be enabled for the app to be fully functional.
  • language: (default null) A BCP-47 language tag. The language can be changed on the fly. If a language is not provided, views will stay in loading-state until one is provided.
  • onTokenRequired: Callback to request a new token. See Authentication section and platform-specific documentation for details. The callback will be called whenever the SubaioManager needs new token information (including if the user is logged out). See TokenRequiredCallback and the Authentication section.
  • sslPinningConfiguration: Bind SSL to select domains with predefined certificate hashes. This is only available on iOS and Android, with very different configurations. See SSL Pinning section.

Example initialization (found in Example/LoadingViewController.swift):

SubaioManager.shared.configure(using: SubaioConfiguration(
    baseUrl: URL(string: "https://sales-widget.demo.subaio.com/")!,
    allowExternalUrls: true,
    allowShare: true,
    sslPinningConfiguration: SubaioSSLPinningConfiguration(
        sites: [
            .init(
                domain: "subaio.com",
                publicKeyHashes: [
                    "IHDUkIMY3xOw7Rx3DvU4gPNXtbVgKsCcT8FR63Z205I=",
                    "YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="
                ]
            )
        ]
    ),
    onTokenRequired: onTokenRequired)
) { [weak self] result in
    DispatchQueue.main.async {
        // Configuration completed
    }
}

SubaioManager.shared.language = "en"

Instantiating a SubaioView

The SubaioView is a UIView that can be inserted in a controller. An example of a controller wrapping a navigation bar and a SubaioView can be found in Example/SubaioViewController.swift.

Instantiation requires a Page and a SubaioViewDelegate implementing event handlers like so:

let view = SubaioView(page: self.page)
view.delegate = delegate
return view

The delegate needs to handle the following events:

  • navigatedTo: Handles navigation to a new Page. Should likely push a new controller to the navigtion stack.
  • back: Handles navigation back. Should likely be handled by popping the current view-controller from the stack.
  • changedStatusTo: Called whenever the view changes status. It can be safely ignored. Can be used to implement a custom loading-screen by hiding the loading-screen and showing the view on a change to running or errored, or to implement a custom error-screen by hiding the view and showing an error page on a change to errored.
  • updatedTitleTo: Called whenever the view changes title. If a host application controlled navigation bar is used, this text should be shown there. Otherwise it can be safely ignored.
  • didReceiveError: Called whenever the view receives an error.
    • noTemplate: Should be handled by showing an error page. Occurs when the SubaioManager has failed to download its initial payload.
    • viewTimedOut: Should be handled by showing an error page. Occurs if the view fails to initialize after 30 seconds. Likely caused by a lack of network without a valid cache of the embedded app.
    • internalError: Does not need to be handled as the SubaioView will show its own error page.
  • isAttemptingToShare: Called when the view attempts to open a share dialog.

The delegate may be implemented directly on the controller, as shown in the example.

Push notifications

Subaio is able to generate several different notifications, e.g.

  • new subscriptions found
  • message regarding cancellation
  • cancellation completed

These notifications are sent from Subaio to the backend of the host project, which in turn decides how/if the notification is presented to the user.

The push notification contains information identifying the user, a user facing message, and a payload with details regarding which component should be shown if the notification is activated.

To reduce the amount of maintenance required by the host project, the library provides a method that can be parsed the notification payload which then is turned into a navigation event to reuse the logic implemented there.

Adding to Xcode project

With Carthage

This library uses Carthage for dependency management, so install Carthage with (or another method found at https://github.com/Carthage/Carthage):

brew install carthage

Once Carthage is installed you build the dependencies with:

carthage bootstrap

Now you are ready to generate the universal binary.

  • Open Subaio.xcodeproj
  • Build the scheme Subaio-Universal
  • Once done the framework is located at ./universal-framework/Subaio.framework

NOTE: Due to it being a universal binary you have to use the script ./scripts/strip-unwanted-architectures.sh in order to not have it rejected by Apple due to having Simulator symbols.

This is most easily done by simply copying the script into Build Phases as the last step for your app.

Build documentation

Install jazzy gem

$ gem install --user-install jazzy

Run jazzy gem to generate documentation

$ ~/.gem/ruby/2.3.0/bin/jazzy