17
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[iOS13] SceneDelegateでDynamicLinksからのURLをハンドリングする

Last updated at Posted at 2020-03-07

環境

  • Xcode 11.3
  • Swift 5.1.3
  • Firebase 6.16.0
  • FirebaseDynamicLinks 4.0.7

経緯

「DynamicLinksからアプリを起動した際に、iOS13系でURLをハンドリングできていない」
という問題に最近対応しました。

結局、マルチウィンドウを活用していないことから、SceneDelegateを破棄することで対応しましたが、調べたもの達が可哀想なので供養するために記事にしました。

ちなみにSceneDelegateの破棄対応は3つで完結します。

  • SceneDelegate.swift を削除
  • info.plist から Application Scene Manifest のkeyを削除
  • プロジェクト作成時にAppDelegate に自動で組み込まれる func application(_:configurationForConnecting:options:)func application(_:didDiscardSceneSessions:) を削除

原因

iOS13から UIApplicationDelegatefunc application(_:continue:restorationHandler:) がDynamicLinksから起動した時に呼び出されなくなっていました。
iOS12以前では前述のメソッドで受け取る userActivitywebpageURL を使って下記のようにできるのですが、

func application(_ application: UIApplication,
                 continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    print(userActivity.webpageURL!)
}

URLは何処へ?:thinking:

初期対応

UISceneDelegate でUserActivityを受け取れるメソッドがあるだろうと探したら、ちゃんとありました。
func scene(_:continue:) (公式ドキュメント)

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    print(userActivity.webpageURL!)
}

良かった、これで一件落着...

と思いきやです

問題

アプリを起動していない時にDyanmicLinksのURLを叩くと先のメソッドが反応しません。
バックグラウンド状態にしておけばちゃんとハンドリングしてくれます。

.....どういうこと:thinking:

解決策

同じ悩みを抱えていたこちらの方の記事のおかげで解決しました
Handling Firebase Dynamic Links in iOS 13 with Scene Delegate

From connectionOptions we need to get the activity.webpageURL object

おぉ...

どうやらSceneDelegateの func scene(_:willConnectTo:options:) (公式ドキュメント) に必要な情報が付与されているとのこと。

第3引数に渡されている UIScene.ConnectionOptions (公式ドキュメント)にはUIKitがsceneを生成する際に、生成された際の情報を紐づけてくれているらしく、その中にUserActivityも含まれていました。

以下のようにしてURLを取り出せます

func scene(_ scene: UIScene,
           willConnectTo session: UISceneSession,
           options connectionOptions: UIScene.ConnectionOptions) {
    // window生成の記述は省略
    guard let userActivity
        = connectionOptions.userActivities
            .first(where: { $0.webpageURL != nil }) else { return }
    print(userActivity.webpageURL!)
}

これで本当の一件落着です。

余談

iPad(iPadOS)ではSafariを開いた際にUserAgentが変わったことが原因か、
そもそもDynamicLinksが機能しない、みたいな問題もありました。
おそらくリンクのparam設定の問題だったのか、こちらの問題はヌルッと解決しました。
ダイナミックリンクURLを手動で構築する

17
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?