Usage (Without PowerAuth)

Usage of this SDK is highly dependent on your use case. The following sections show common usage scenarios and principles.

Naming conventions

  Explanation
Transport Data Data that will be transported from the Source App to the Target App.
Source App Application that is starting the activation spawn process (will transfer the data).
Target App Application that will be installed (if not already) or retrieve data.

Integrating into the Source App

  1. Define the Target App in your code:
  import WultraActivationSpawn
  
  let app = WASApplication(
      // URL deeplink scheme (for example from myAppScheme://settings)
      deeplinkScheme: "myAppScheme",
      // from apps.apple.com/us/app/AppName/id123456789 
      appStoreIdentifier: 123456789
  )
  1. Declare deeplink “permissions” for the URL scheme of Target App in the Info.plist of the Source App.

Deeplink scheme settings

  1. Integrate into your UIViewController.
  • Sample implementation:

    import UIKit
    import WultraActivationSpawnBasic
        
    class SampleViewController: UIViewController {
            
        @IBOutlet weak var installButton: UIButton!
        @IBOutlet weak var transferButton: UIButton!
            
        // Additional data for generator (must be the same for both Source and Target App).
        let additionalData: Data = "myAdditionalData".data(using: .utf8)!
        // Additional data for transporter (must be the same for both Source and Target App).
        var sharedInfo: Data?
            
        // Transporter moves Activation Data to Target App.
        private var transporter: WASTransporter?
            
        private func prepareInstances() -> Bool {
            do {                
                // Note that the additionalData must be the same
                // for both Target and Source App. Please consult with Wultra
                // which configuration suits your needs.
                transporter = try WASTransporter(config: .semiStable(sameTeam: true, validityInSeconds: 10), additionalData: additionalData)
                    
                return true
                    
            } catch let e {
                // failed to create the transporter
                return false
            }
        }
            
        override func viewDidLoad() {
            super.viewDidLoad()
                
            // make sure all instances are ready
            guard prepareInstances() else {
                installButton.isHidden = true
                transferButton.isHidden = true
                // show error UI
                return
            }
                
            refreshButtons()
        }
            
        private func refreshButtons() {
            do {
                let installed = try app.isInstalled()
                installButton.isHidden = installed
                transferButton.isHidden = !installed
            } catch let error {
                // Failed to check if installed.
                // Deeplink scheme invalid or not declared in the Info.plist.
                // See the "error" variable for details.
            }
        }
            
        @IBAction func installClick(_ sender: UIButton?) {
            // Extension function from WultraActivationSpawn module.
            // Opens the AppStore sheet with given application for user to install.
            self.openAppStoreProductPage(application: app) {
                // refresh button status
                self.refreshButtons()
            }
        }
            
        @IBAction func transferClick(_ sender: UIButton?) {
            
            // create some data you want to transfer
            let data = "myDataToTransfer.data(using: .utf8)!
                
            // Send it to the Target App. This might prompt the user if he wants to open the application.
            // Use can use annotated for passing additional data.
            //  - "annotated" string is passed in the deeplink unencrypted (just base64 encoded) and can 
            //    be retrieved with `WASTransported.validate` method. In this example, we're sending name of the source app
            self.transporter?.transport(data: data, to: app, annotated: "mySourceApp", with: self.sharedInfo) { transportResult in
            // process the transport result
        }
    }
    

Integrating into the Target App

  1. Declare a URL scheme for the application to enable digesting the deeplink.

Deeplink scheme settings

  1. Retrieve the activation data from a deeplink.
 import UIKit
 import WultraActivationSpawnBasic
 
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate {
 
     // Additional data for processor (must be the same for both Source and Target App).
     let additionalData: Data = "myAdditionalData".data(using: .utf8)!
     // Shared data for processor (must be the same for both Source and Target App).
     var sharedInfo: Data?
 
     func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
            
         do {
             // Note that the additionalData must be the same
             // for both Target and Source App.
             let processor = WASProcessor(additionalData: additionalData)
             
             // First, validate the deeplink if it's valid activation-spawn deelink
             // and retreive annotation data (when available)
             let validationResult = transporter.validate(deeplink: url)
             
             switch validationResult {
             case .success(let data):
                 print(data.annotation) // prints "mySourceApp" as set in the example above (Source App integration)
             case .failure(let e):
                 // not a valid Activation Spawn deeplink
                 // do some error handling
                 return false
             }
                
             // extract data from deeplink
             let data = try transporter.process(deeplink: url, with: sharedInfo)
             // .. process the data
                
             return true // mark deeplink as accepted
         } catch let error {
             // process error
             return false
         }
     }
 }

Passing custom data

For your convenience, you can pass custom data from the Source App to the Target App.

annotation

Annotation is a string in the deeplink and is accessible without the need to decrypt the data.

This is good for example if you want to pass some data that will help you with decoding, like the id of the Source App or other public data. Always assume that the annotation data can be logged as plain-text in the system console.

Example usage of annotation:

// In the source app:
transporter.transport(data: data, to: app, annotated: "mySourceApp") { transportResult in
    // Process the transport result
}

// In the target app
let validationResult = transporter.validate(deeplink: url)
             
switch validationResult {
case .success(let data):
    print(data.annotation)
case .failure(let e):
    // not a valid Activation Spawn deeplink
    // do some error handling
}

Error handling and logging

If you have a problem with syncing your Source and Target App configuration, we recommend turning on debug logging by WASLogger.verboseLevel = .debug

Exceptions

All methods that can produce an error are throwing various exceptions (as described in the in-code documentation).

All exceptions implement CustomStringConvertible protocol where details about the exception and possible solutions are explained (in the description property). We highly recommend logging these exceptions into your log system as they provide great debug value about what went wrong.

Logging

You can set up logging for the library using the WASLogger class.

Verbosity Level

You can limit the amount of logged information via the verboseLevel property.

Level Description
off Silences all messages.
errors Only errors will be logged.
warnings (default) Errors and warnings will be logged.
info Error, warning and info messages will be logged.
debug All messages will be logged.

Logger Delegate

In case you want to process logs on your own (for example log into a file or some cloud service), you can set WASLogger.delegate.

Last updated on Jul 08, 2024 (07:34) Edit on Github Send Feedback
Search

3.2.x

Activation Spawn SDK for iOS