Skip to content

Commit

Permalink
[ABW-3437] Implement deferred deep link solution (#1176)
Browse files Browse the repository at this point in the history
  • Loading branch information
matiasbzurovski authored Jun 28, 2024
1 parent 5a676d2 commit bb43174
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
// MARK: - AppsFlyerClient
struct AppsFlyerClient: Sendable {
/// Method to be called once on app start.
var start: Start

/// Method to be called every time the `AppDelegate`/`SceneDelegate` is called to continue
/// with a user activity.
///
/// Note: such methods aren't actually called right now on neither of those classes. However, given AppsFlyer documentation
/// indicates that we should delegate the call to their lib (so that it can resolves deferred deep links), I am adding support for it
/// in case the situation changes in the future.
var `continue`: Continue
}

// MARK: AppsFlyerClient.Start
extension AppsFlyerClient {
typealias Start = @Sendable () -> Void
typealias Continue = @Sendable (NSUserActivity) -> Void
}

extension DependencyValues {
Expand Down
30 changes: 30 additions & 0 deletions RadixWallet/Clients/AppsFlyerClient/AppsFlyerClient+Live.swift
Original file line number Diff line number Diff line change
@@ -1,26 +1,56 @@
import AppsFlyerLib

// MARK: - AppsFlyerClient + DependencyKey
extension AppsFlyerClient: DependencyKey {
static var liveValue: AppsFlyerClient {
@Dependency(\.sensitiveInfoClient) var sensitiveInfoClient
let state = State()

actor State {
let delegate = Delegate()
}

return .init(
start: {
guard
let devKey = sensitiveInfoClient.read(.appsFlyerDevKey),
let appId = sensitiveInfoClient.read(.appsFlyerAppId)
else {
loggerGlobal.info("Skipping AppsFlyer start as keys are missing")
return
}
AppsFlyerLib.shared().appsFlyerDevKey = devKey
AppsFlyerLib.shared().appleAppID = appId

AppsFlyerLib.shared().deepLinkDelegate = state.delegate

#if DEBUG
AppsFlyerLib.shared().isDebug = true
#endif

AppsFlyerLib.shared().start()
},
continue: { userActivity in
AppsFlyerLib.shared().continue(userActivity)
}
)
}

private class Delegate: NSObject, DeepLinkDelegate, @unchecked Sendable {
func didResolveDeepLink(_ result: DeepLinkResult) {
if let deepLink = result.deepLink {
loggerGlobal.info("did resolve deep link. Is deferred: \(deepLink.isDeferred). Click events: \(deepLink.clickEvent)")
if deepLink.isDeferred {
let message = if let deepLinkValue = deepLink.clickEvent["deep_link_value"] as? String {
"Resolved deferred DL with value \(deepLinkValue)"
} else {
"Resolved deferred DL without value"
}
AppsFlyerLib.shared().logEvent(message, withValues: deepLink.clickEvent)
}
} else if let error = result.error {
loggerGlobal.info("failed to resolve deep link. Status: \(result.status), Error: \(error.localizedDescription)")
}
}
}
}
8 changes: 7 additions & 1 deletion RadixWallet/Features/AppFeature/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import ComposableArchitecture
import SwiftUI

// MARK: - AppDelegate
public final class AppDelegate: NSObject, UIApplicationDelegate {
@Dependency(\.appsFlyerClient) var appsFlyerClient

public func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
Expand All @@ -13,9 +16,12 @@ public final class AppDelegate: NSObject, UIApplicationDelegate {
}

public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
@Dependency(\.appsFlyerClient) var appsFlyerClient
appsFlyerClient.start()
return true
}

public func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([any UIUserActivityRestoring]?) -> Void) -> Bool {
appsFlyerClient.continue(userActivity)
return true
}
}
5 changes: 5 additions & 0 deletions RadixWallet/Features/AppFeature/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public final class SceneDelegate: NSObject, UIWindowSceneDelegate, ObservableObj
}
}

public func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
@Dependency(\.appsFlyerClient) var appsFlyerClient
appsFlyerClient.continue(userActivity)
}

func overlayWindow(in scene: UIWindowScene) {
let overlayView = OverlayReducer.View(
store: .init(
Expand Down
2 changes: 1 addition & 1 deletion fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ platform :ios do
end

desc "Installs distribution certificates"
desc "Usage `bundle exec fastlane ios install_distribution_certificate --env ios.<specific env>`"
desc "Usage `bundle exec fastlane ios install_distribution_certificates --env ios.<specific env>`"
lane :install_distribution_certificates do
code_signing(type: "appstore")
end
Expand Down
2 changes: 1 addition & 1 deletion fastlane/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Archive and export the iOS app

Installs distribution certificates

Usage `bundle exec fastlane ios install_distribution_certificate --env ios.<specific env>`
Usage `bundle exec fastlane ios install_distribution_certificates --env ios.<specific env>`

### ios install_development_certificates

Expand Down

0 comments on commit bb43174

Please sign in to comment.