简体   繁体   中英

Xcode 13 Universal Links for both iOS 13+ and 12

I have an app that supports a min. of iOS 9. But, I am thinking to support min. iOS 12 (I know the best practice is to support min n-2 already)

In this app, I don't have SceneDelegate but only have AppDelegate . I am trying to open up universal links on my iOS 15 real device.

Also, I know some of AppDelegate functions like below doesn't work on iOS 13+ devices.

application(_ application: UIApplication, continue userActivity: NSUserActivity, 
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool

Instead of AppDelegate , I already know, I should use SceneDelegate 's following function:

scene(_ scene: UIScene, continue userActivity: NSUserActivity)

My SceneDelegate willConnectTo function like following:

guard let _ = (scene as? UIWindowScene) else { return }
let viewController = Storyboard.launchScreen.instantiate(from: .main)
if let windowScene = scene as? UIWindowScene {
  self.window = UIWindow(windowScene: windowScene)
  self.window?.rootViewController = viewController
  self.window?.makeKeyAndVisible()
}

(Also, above rooting codes implemented in AppDelegate 's didFinishLaunchingWithOptions )

But when I implement all of the SceneDelegate functions to my app, I am seeing a black blank screen at the first launch.

I am getting these logs:

[SceneConfiguration] Info.plist configuration "Default Configuration" for 
UIWindowSceneSessionRoleApplication contained UISceneDelegateClassName key, 

but could not load class with name "My_APP.SceneDelegate".

[SceneConfiguration] Info.plist configuration "(no name)" for 
UIWindowSceneSessionRoleApplication contained UISceneDelegateClassName key, 
but could not load class with name "My_APP.SceneDelegate".

What have I done for Universal links so far?

(Above step creates Debug/Release.entitlements automatically both in Xcode and developer.apple.com )

  • apple-app-site-association website already has SSL certificates.
  • I have Main.storyboard at the first launch.
  • My Info.plist is like following:
<key>UIApplicationSceneManifest</key>
    <dict>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PROJECT_MODULE_NAME).SceneDelegate</string>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Main</string>
                </dict>
            </array>
        </dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <true/>
    </dict>

Also my apple-app-site-association file:

{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "*****.com.*****.******",
                "paths": [
                    "/",
                    "/titles",
                    "/title/*",
                    "/search"
                ]
            }
        ]
    }
}

After spending 2 weeks on solution, I did followings:

It wasn't about adding SceneDelegate . So, if you don't have any multiple scene scenarios in your app you don't need to add SceneDelegate .

open func application(_ application: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = Storyboard.launchScreen.instantiate(from: .main)
    window?.makeKeyAndVisible()

    handleDeepLink()

    migrateLoginDetails()
      .andThen(updateConfiguration)
      .andThen(updateTitles)
      .subscribe { [unowned self] _ in
        Theme.apply()

        let rootViewController = Storyboard.main.instantiate()
        self.window?.rootViewController = rootViewController
        self.didSetWindowRootViewController.onNext(rootViewController)
        Updater.sharedInstance().showUpdateWithConfirmation(in: rootViewController)
      }
      .disposed(by: disposeBag)
    }

handling DeepLinks for opening corresponding URL:

private func handleDeepLink() {
    shouldHandleLink
      .flatMap { [didSetWindowRootViewController] url in
        didSetWindowRootViewController.map { ($0, url) }
      }
      .observe(on: MainScheduler.instance)
      .subscribe(onNext: { vc, url in
        URLHandler.shared.open(url: url, from: vc)
      })
      .disposed(by: disposeBag)
  }

After updating didFinishLaunching method in AppDelegate userActivity method called anymore.

public func application(_: UIApplication,
                      continue userActivity: NSUserActivity,
                      restorationHandler _: @escaping 
([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
      let incomingURL = userActivity.webpageURL else {
  return false
 }
 shouldHandleLink.onNext(incomingURL)
 return true
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM