GuidesAPI GuideChangelog
Log In
Guides

Appsflyer Integration

This chapter how to configure Appsflyer in your app when using Saucelive.

1. Appsflyer SDK

iOS

Installing the Appsflyer SDK

Install the Appsflyer SDK using CocoaPods:

# Podfile
platform :ios, '10.0'
target 'YourApp' do
  use_frameworks!
  pod 'AppsFlyerFramework'
end

Then runpod install in the terminal.

Initial Appsflyer SDK Setup

Update your AppDelegate.swift file to initialize the SDK:

import UIKit
import AppsFlyerLib

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        AppsFlyerLib.shared().appsFlyerDevKey = "YOUR_DEV_KEY"
        AppsFlyerLib.shared().appleAppID = "YOUR_APP_ID"
        AppsFlyerLib.shared().delegate = self
        AppsFlyerLib.shared().isDebug = true
        return true
    }

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        AppsFlyerLib.shared().handleOpen(url, options: options)
        return true
    }

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        AppsFlyerLib.shared().continue(userActivity, restorationHandler: nil)
        return true
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        AppsFlyerLib.shared().start()
    }
}

extension AppDelegate: AppsFlyerLibDelegate {
    func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) {
        // Conversion data received
    }

    func onConversionDataFail(_ error: Error) {
        // Conversion data failed
    }

    func onAppOpenAttribution(_ attributionData: [AnyHashable : Any]) {
        // App open attribution data received
    }

    func onAppOpenAttributionFailure(_ error: Error) {
        // App open attribution data failed
    }
}

Android

Installing the Appsflyer SDK

Add the Appsflyer SDK to your build.gradle file:

dependencies {
    implementation 'com.appsflyer:af-android-sdk:6.+'
}

Initial Appsflyer SDK Setup

Update your MyApplication.kt file to initialize the SDK:

import android.app.Application
import com.appsflyer.AppsFlyerLib
import com.appsflyer.AppsFlyerConversionListener
import org.json.JSONObject

class MyApplication : Application() {

    companion object {
        private const val AF_DEV_KEY = "YOUR_DEV_KEY"
    }

    override fun onCreate() {
        super.onCreate()

        AppsFlyerLib.getInstance().init(AF_DEV_KEY, object : AppsFlyerConversionListener {
            override fun onConversionDataSuccess(conversionData: Map<String, Any>) {
                // Conversion data received
            }

            override fun onConversionDataFail(errorMessage: String) {
                // Conversion data failed
            }

            override fun onAppOpenAttribution(attributionData: Map<String, String>) {
                // App open attribution data received
            }

            override fun onAttributionFailure(errorMessage: String) {
                // App open attribution data failed
            }
        }, this)
        AppsFlyerLib.getInstance().start(this)
    }
}

2. WebView and Bridge Configuration

iOS

WKWebView Setup

Configure WKWebView in your ViewController.swift and add a JavaScript bridge:

import WebKit
import AppsFlyerLib

class ViewController: UIViewController, WKScriptMessageHandler {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let contentController = WKUserContentController()
        contentController.add(self, name: "sauceflexSendAppsFlyerEvent")

        let config = WKWebViewConfiguration()
        config.userContentController = contentController

        webView = WKWebView(frame: self.view.bounds, configuration: config)
        self.view.addSubview(webView)

        if let url = URL(string: "https://yourwebsite.com") {
            webView.load(URLRequest(url: url))
        }
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if let messageBody = message.body as? String,
           let data = messageBody.data(using: .utf8),
           let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
           let event = json["event"] as? String,
           let params = json["params"] as? [String: Any] {
            handleEvent(event, params)
        }
    }

    func handleEvent(_ event: String, _ params: [String: Any]) {
        AppsFlyerLib.shared().logEvent(event, withValues: params)
    }
}

Android

WebView Setup

Configure WebView in your MainActivity.kt and add a JavaScript interface:

import android.os.Bundle
import android.webkit.JavascriptInterface
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import com.appsflyer.AppsFlyerLib
import org.json.JSONObject

class MainActivity : AppCompatActivity() {

    private lateinit var webView: WebView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        webView = findViewById(R.id.webView)
        val webSettings: WebSettings = webView.settings
        webSettings.javaScriptEnabled = true
        webView.webViewClient = WebViewClient()
        webView.loadUrl("https://yourwebsite.com")

        webView.addJavascriptInterface(WebAppInterface(), "sauceflexSendAppsFlyerEvent")
    }

    private class WebAppInterface {

        @JavascriptInterface
        fun sauceflexSendAppsFlyerEvent(message: String) {
            try {
                val json = JSONObject(message)
                val event = json.getString("event")
                val params = json.getJSONObject("params")
                AppsFlyerLib.getInstance().logEvent(this@MainActivity, event, toMap(params))
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        private fun toMap(jsonObj: JSONObject): Map<String, Any> {
            val map = mutableMapOf<String, Any>()
            val keys: Iterator<String> = jsonObj.keys()
            while (keys.hasNext()) {
                val key = keys.next()
                val value = jsonObj.get(key)
                map[key] = value
            }
            return map
        }
    }
}

3.Verifying Event Logging

iOS

Use the completion handler in Appsflyer’s logEvent method to verify whether the event was successfully logged:

func handleEvent(_ event: String, _ params: [String: Any]) {
    AppsFlyerLib.shared().logEvent(event, withValues: params) { (response, error) in
        if let error = error {
            print("Event failed: \(error.localizedDescription)")
        } else {
            print("Event succeeded: \(response ?? [:])")
        }
    }
}

Android

Use the callback in logEvent to verify whether the event was successfully logged:

@JavascriptInterface
fun sauceflexSendAppsFlyerEvent(message: String) {
    try {
        val json = JSONObject(message)
        val event = json.getString("event")
        val params = json.getJSONObject("params")
        AppsFlyerLib.getInstance().logEvent(this@MainActivity, event, toMap(params)) { eventName, eventValue, error ->
            if (error != null) {
                println("Event failed: $error")
            } else {
                println("Event succeeded: $eventValue")
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}