iOS deferred deep linking with iOS Private Relay

iOS 15上线后,Apple向iCloud+用户提供Private Relay(保密传送)服务,用户可通过此功能对其网页浏览记录加密并隐藏其确切地址、IP地址及其浏览内容。如果用户启用了Private Relay,可能会对归因及延迟深度链接产生干扰。也就是说,如果未安装应用的用户从App Store安装并打开应用后, Private Relay会阻止其跳转到应用中的具体页面。

您可以使用以下任意一个AppsFlyer解决方案来确保延迟深度链接(DDL)正常生效:

  • 【推荐】App Clip方案:您可以创建一个App Clip(苹果小程序),然后通过这个App Clip来获取用户归因数据,并为用户提供定制化的App Clip体验,这跟DDL能实现的功能一样。您还可以在App Clip中添加一条路径,把用户从App Clip引导到完整版应用。
  • 剪贴板方案:创建一个落地页,用来复制URL中的延迟深度链接的数据,并让用户跳转到应用中指定的页面。请注意:此方案不能解决归因问题。

App Clip解决方案

前期准备:接入AppsFlyer SDK V6.4.0或以上版本

请按以下步骤配置基于App Clip的DDL方案

  1. Follow the Apple instructions and develop an App Clip that provides the desired user journey.
  2. Integrate the AppsFlyer SDK for App Clips, including App Clip-to-full app attribution.
  3. In the App Clip sceneDelegate:
    • Replace scene continue userActivity with the following function:
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
  // Must for AppsFlyer attrib
  AppsFlyerLib.shared().continue(userActivity, restorationHandler: nil)

  //Get the invocation URL from the userActivity in order to add it to the shared user default
  guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
  let invocationURL = userActivity.webpageURL else {
    return
  }
  addDlUrlToSharedUserDefaults(invocationURL)        
}

⇲ Github链接:Swift

  • 添加以下方法:
func addDlUrlToSharedUserDefaults(_ url: URL){
  guard let sharedUserDefaults = UserDefaults(suiteName: "group.<your_app>.appClipToFullApp") else {
    return
  }
  //Add invocation URL to the app group
  sharedUserDefaults.set(url, forKey: "dl_url")
  //Enable sending events
  sharedUserDefaults.set(true, forKey: "AppsFlyerReadyToSendEvents")
}

⇲ Github链接:Swift

  1. In the full app:
    • In appDelegate, add the following method:
func deepLinkFromAppClip() {
  guard let sharedUserDefaults = UserDefaults(suiteName: "group.<your_app>.appClipToFullApp"),
  let dlUrl = sharedUserDefaults.url(forKey: "dl_url")
  else {
    NSLog("Could not find the App Group or the deep link URL from the app clip")
    return
  }
  AppsFlyerLib.shared().performOnAppAttribution(with: dlUrl)
  sharedUserDefaults.removeObject(forKey: "dl_url")
}

⇲ Github链接:Swift

  • At the end of the application didFinishLaunchingWithOptions launchOptions method, call deepLinkFromAppClip:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

  // ...

  deepLinkFromAppClip()

  return true
}

⇲ Github链接:Swift

剪贴板解决方案

To set up the clipboard-based solution:

  1. Enter the following code in appDelegate.
NSString *pasteboardUrl = [[UIPasteboard generalPasteboard] string];
NSString *checkParameter = @"cp_url=true";

if ([pasteboardUrl containsString:checkParameter]) {
  [[AppsFlyerLib shared] performOnAppAttributionWithURL:[NSURL URLWithString:pasteboardUrl]];
}
var pasteboardUrl = UIPasteboard.general.string ?? ""
let checkParameter = "cp_url=true"

if pasteboardUrl.contains(checkParameter) {
    AppsFlyerLib.shared().performOnAppAttribution(with: URL(string: pasteboardUrl))
}
  1. 添加代码,把剪贴板里的延迟深度链接数据粘贴到URL中。该操作不在AppsFlyer SDK的控制范围内。