概要
iOS13以降からUISceneDelegate
が導入されたのでUniversal Linkからアプリが起動された挙動もUISceneDelegate
のライフサイクルで制御します。
遷移したURLによってiOS側で制御を行いたいと思いますので、そちらを試した結果を記します。
実装
Universal Linkを利用するためのapple-app-site-association
の設置やAssociated Domains
の設定は完了しているものとします。
XCode11以降で作成されたプロジェクトにはSceneDelegate.swift
が含まれていてこちらにてライフサイクルの制御が管理されています。
Universal LinkなどをつかってSafariなどから遷移してきたときはscene(_:continue:)
というDelegateメソッドで補足されます。
https://developer.apple.com/documentation/uikit/uiscenedelegate/3238056-scene
NSUserActivity
にwebpageURL
というプロパティが存在するのでこちらでURLを取得しURLによって表示する画面などを決めて遷移できます。
以下はhogehoge
というパスのURLでアプリに遷移した際にHogeHogeViewController
をモーダル表示するときの実装です。
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb else { return }
guard let url = userActivity.webpageURL else { return }
if url.scheme == "https" && url.host == "example.jp" && url.path == "hogehoge" {
window?.rootViewController?.present(HogeHogeViewController(), animated: true, completion: nil)
}
}
問題
上記の実装でUniversal Linkから遷移を制御できるのですが、こちらはアプリがバックグラウンドで起動中しか保続できません。
新規にアプリが起動するときを制御するにはscene(_:willConnectTo:options:)
にて同様の処理を用意する必要があります。
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// URLが存在するものを補足
guard let userActivity = connectionOptions.userActivities.first(where: { $0.webpageURL != nil }) else { return }
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb else { return }
if url.scheme == "https" && url.host == "example.jp" && url.path == "hogehoge" {
window?.rootViewController?.present(HogeHogeViewController(), animated: true, completion: nil)
}
}
こちらでアプリが起動していない場合でも画面の制御を行うことができるようになります。
あとがき
scene(_:continue:)
だけだと未起動時の制御を補足できないですが、起動していないので実装時に見落としてしまいがちなのとデバッグがしにくく、ハマってしまうこともあるかとも思います。
こちらが役に立てば。