iOS, Swift, SwiftUI

[iOS 14]WidgetでDeep Link作成

iOS 14からWidgetという機能が登場しました。これはアプリを起動しなくてもHome画面にアプリ情報をユーザーに届けられる機能です。

今回はWidgetをタップした時に特定のアプリ画面が開けるようにする、Deep Linkの作成方法について解説します。

検証環境

  • Xcode 12.2
  • iOS 14.2

WidgetとDeep Link

Widgetをタップすると何も実装しなければ、本体アプリが起動されます。

----------2020-11-26-0.15.40

しかし、Widgetに表示されているコンテンツと関連した画面に遷移できればユーザー体験が向上します。
そのためにはWidgetにDeep Linkを作る必要があります。

Widgetのサイズとリンクの数について

まず最初にWidgetのサイズとリンクの数についてお話します。
開発者が作れるWidgetの大きさはSmall, Medium, largeの3つです。

----------2020-12-01-0.23.16

実はWidgetはサイズによっておけるリンクの数が決まっています。
Smallサイズはひとつだけで、MediumサイズとLargeサイズは複数置くことができます。
例えば、Appleの株アプリはSmallサイズですとアプリを起動しますが、
Mediumサイズ、Largeサイズですとタップした銘柄の詳細画面に飛ぶようになっています。

WidgetでDeep Linkを作る方法

WidgetでDeep Linkを作る方法は2つあります。

.widgetURL修飾子を使う方法とLinkViewを使う方法です。

.widgetURL

.widgetURL修飾子の使い方はリンクしたいViewに追加します。
するとそのViewをタップすると.widgetURL修飾子で渡したURLをアプリでハンドリングできるようになります。

HStack {
    Text("Link by widgetURL")
        .widgetURL(URL(string: "example://deeplink?from=widget"))
}

注意としてひとつのWidget Viewに.widgetURLはひとつしか使えません。
複数置いてもエラーにはならないですが、意図しないリンクが作られることがあるので、ひとつだけにとどめましょう。
なのでSmall サイズに使うと良いです。

LinkはリンクしたいViewの親ビューにすることでリンクを作成できるViewです。
destinationにURLを渡します。

VStack {
    Link(destination: URL(string: "example://deeplink?from=widget&id=1")!, label: {
        Text("Link by Link")
    })
    Link(destination: URL(string: "example://deeplink?from=widget&id=2")!, label: {
        Text("Link by Link")
    })
    Link(destination: URL(string: "example://deeplink?from=widget&id=3")!, label: {
        Text("Link by Link")
    })
}

Linkは、.widgetURLと異なり、ひとつのWidget Viewに複数置いても大丈夫なのでMediumサイズやLargeサイズで使うといいでしょう。

アプリでURLを受け取る方法

つづいて、.widgetURLLinkで作ったリンクをユーザーがタップした後、アプリ側でハンドリングする方法について解説します。

SwiftUIの.onOpenURLを使う

皆さんのアプリがすでにSwiftUIに対応しているなら.onOpenURL修飾子があります。
widgetから渡されたurlを取得できるので、このurlで詳細画面を開くなどのハンドリングをしましょう。

struct ContentView: View {
    var body: some View {
        NavigationView {
            ...
        }
        .onOpenURL(perform: { url in
            // do somethink
        })
    }
}

SceneDelegateのopenURLContextsを使う

みなさんのアプリがまだSwiftUI対応していない場合は、SceneDelegateのopenURLContextsが使えます。
こちらから取得したurlをハンドリングしましょう。

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        print(URLContexts.first?.url)
    }
}

まとめ

WidgetでDeep Linkを作成する方法を解説しました。
Widget側では.widgetURLLinkを使いURLを渡します。
アプリ側では.onOpenURLopenURLContextsを使ってそのURLを受け取ります。
URLからで対象の画面に遷移するなどの処理を追加することでDeep Linkを実装できます。

ぜひ皆さんも試してください。

動画バージョン

本記事の内容は2020年11月26日に行われたBitrise社主催のSwift開発座談会に先立ち公開された動画と同じものです。
ぜひ動画の方も御覧ください。

宣伝

インプレスR&D社より、「1人でアプリを作る人を支えるSwiftUI開発レシピ」発売中です。
「SwiftUIでアプリを作る!」をコンセプトにSwiftUI自体の解説とそれを組み合わせた豊富なサンプルアプリでどんな風にアプリ実装すればいいかが理解できる本となっています。
iOS 14対応、Widgetの作成も一章まるまるハンズオンで解説しています。

この記事のWidgetのDeep Linkの内容はもちろん、URLをハンドリングして具体的に特定の画面へ遷移させる内容も解説しています。

SwiftUIを学びたい方、ぜひこちらのリンクをチェックしてください!




https://nextpublishing.jp/book/12491.html

Author image

About Sato Takeshi

  • Tokyo, Japan