ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
制約されたネットワークでローカルプッシュ接続性を構築する
ローカルプッシュ接続性を活用し、Appサーバーからネットワーク上のデバイスへ、インターネット接続の無い状況でも通知を配信できます。制約されたネットワーク環境で実行するApp向けに通知を構築する方法、期待されるインターネット接続時と同様の信頼性と体験を提供しコミュニケーションを継続するための通知を構築する方法をお伝えします。この技術を利用したくなった時にApp内でどう実装するか、テクニカルな詳細も説明します。
リソース
-
ダウンロード
こんにちは WWDCへようこそ
“制約されたネットワークで ローカルプッシュ接続性を構築する” パレッシュ・サワントです 本日はiOS 14の新機能 ローカルプッシュ接続APIについてお話しします プッシュ通知はアプリケーションユーザに対し タイムリーで関連性の高い情報を 知らせ続けることができるすばらしい技術です しかし プッシュ通知はAppleのプッシュ通知 サービスに依存しています デバイスがインターネットに 接続している時にしか使えません 皆さんからのフィードバックで アプリケーションサーバーから メッセージを受け取る能力が アプリケーションの機能に欠かせず なおかつ インターネット接続がなくても 動作しなくてはならない というご意見がありました アプリケーションへのこの要望を満たすために iOS 14では新しいAPIを追加しました それはWi-Fiネットワークで動作する 独自のプッシュ接続サービスの作成を 可能にします まずAppleのプッシュ通知を おさらいしましょう それから 新しいAPIを使用して カスタムプッシュ通知サービスを 構築する方法をお話しします その後 サンプルアプリケーションを使って この新しい機能のデモを行います そして新しいAPIの使用についての 詳細に進みます では始めましょう 皆さんの多くはプッシュ通知を よくご存知と思います 多くのアプリケーションはプッシュ通知を ニュース速報やスポーツの更新 インスタントメッセージやVoIP電話の受信など その他多くのことに使用しています どのように動作するのか確認しておきましょう プロバイダサーバーから Appleプッシュ通知サービス 別名APNへプッシュ通知依頼を 送ります APNは各対象デバイスに対して 対応する通知ペイロードを運びます 通知を受け取ると システムはデバイス上の適切な アプリケーションにそのペイロードを届けます 通知タイプによって アプリケーションがペイロードを受け取るために PushKitかUserNotificationsの いずれかのフレームワークを使います APNはプッシュ通知機能の中で 最も重要な部分です プッシュ通知はAPN接続またはインターネットが 利用可能なデバイスで使用するには アプリケーションに適したソリューションです デバイス上のすべてのアプリケーションへ 通知を届けるのに最適な方法です デバイスとAPNの間の単一の接続を 実装するからです プッシュ通知はアプリケーションで期待通りの ユーザ体験をもたらします そして最も重要なことに エネルギー効率も良好です したがって デベロッパーは PushKitかUserNotificationの どちらかのフレームワークで サーバーから発信する通知を 取り扱うことを選ぶべきです ただし APNの届かないネットワーク環境で アプリケーションが使われる場合 アプリケーションはこれらの通知を 受け取ることができません たとえば クルーズ船や飛行機 キャンプ場や病院では APN接続が限定されるか まったくないことがあります そうした条件ではアプリケーションのプッシュ 通知機能が万全に働かない可能性があります プッシュ通知は ユーザにタイムリーな情報を提供し ユーザがそれに反応して適切な アクションをとれるよう 重要な役割を果たしています そのため ユーザに重要なことのために 制限されたネットワーク環境でも プッシュ通知が機能し続けるように することが大切です ローカルプッシュ接続は この問題を 解決するために設計されたソリューションです そしてiOS 14にはローカルプッシュ接続APIが 追加されました これはAPIのうちNetworkExtensionファミリーの 新しい一員です どう機能するかみてみましょう この新しいAPIのおかげで ローカルWi-Fiネットワークにある プロバイダサーバーと通信するアプリケーション 拡張機能を構築することができます APNはありませんので プロバイダサーバーと アプリケーション拡張の間で通知を届ける プロトコルを独自で 定義する必要があります アプリケーションユーザ向けの ローカルプッシュ通信を 有効にするWi-Fiネットワークを アプリケーションで指定しておく必要があります デバイスが指定されたWi-Fiネットワークに 接続すると システムが アプリケーション拡張機能を起動します アプリケーション拡張機能はプロバイダサーバーとの ネットワーク接続を維持し 通知を受け取る責任を負います デバイスが指定されたWi-Fiネットワークに 接続しているかぎり アプリケーション拡張機能はバックグラウンドで 実行し続けます デバイスが指定されたWi-Fiネットワークとの 接続を失うとシステムは アプリケーション拡張機能を停止します さて 新しいローカルプッシュ接続APIについて ご説明しました そして標準のプッシュ通知についても 再確認しました そこでアプリケーションにとって正しいAPIを 選択する一般的なガイドラインを ご説明します 一般的なプッシュ通知の要求には PushKitまたはUserNotifications フレームワークの いずれかを選ぶべきです ローカルプッシュ接続APIは 非常に特定されたユースケースの ごく少数の場合のために 設計されています ユースケースは主に ネットワーク環境が限定されていることと その環境におけるユーザの 要求によって定義されます ローカルプッシュ接続は 通知が必要不可欠で ネットワーク環境が制限された場面で 正しいソリューションになりえます ローカルプッシュ接続APIを使った 特定のユースケースを実装するには 新しい権限を 申請する必要があります これらの2つのメカニズムを互いに比較した時 どのような特徴があるか見てみましょう 新しいローカルプッシュ接続はすべて プロバイダサーバーと アプリケーション拡張機能との間の 直接通信です 指定したWi-Fiネットワークで 独自のプロトコルを使用します それは完全にあなたの管理下にあります アプリケーション拡張機能が多様な通知を どのように取り扱うか確認しましょう ユーザ向けの通知を受領すると アプリケーション拡張機能はローカル通知を使い ユーザの注意を惹きます アプリケーション拡張機能コードは UserNotificationsフレームワークを使って ローカル通知を作成して スケジューリングします アラートを表示したり サウンドを再生したり アプリケーションのアイコンに バッジをつけたりできます たとえばテキストメッセージの 通知を受領すると このように画面の上部から 降りてくるバナーで ユーザに通知します アプリケーション拡張機能は 常にユーザローカル通知を使って ユーザに対する通知を行います
ここで アプリケーション拡張機能がVoIP通知を どう扱えるのか見てみましょう この通知は アプリケーションユーザに 着信VoIP通話の情報を伝えます
VoIP通知を受け取ると アプリケーション拡張機能はNEAppPushProvider クラスを使って システムに着信があることを報告します システムはそれに反応して 起動していない場合 親アプリケーションを起動し そこへ着信情報を届けます 親アプリケーションは CallKitフレームワークを使って着信電話のUIを このように表示します 後で アプリケーション内でVoIP通知の取り扱い方 詳細をお話しします それではデモアプリケーションで 動作を見ましょう クルーズ船ではインターネット接続は 限定されているか使用できません または有料データプランが 提供されることもあります このデモではクルーズ船会社がSimplePushという 名前のアプリケーションを開発したとします 新しいローカルプッシュ接続 APIを使用しています テキストメッセージングと VoIPサービスを提供します 乗船中の友人や家族とこのアプリケーションで 連絡を取り合えるようにしたいためです ジェーンとジョンは このアプリケーションの利用者です 彼らはSimplePushアプリケーションを使って 通信しています 彼らのデバイスにはインターネット接続が ありませんが
これはジェーンのデバイスで こちらがジョンのデバイスです ジェーンのデバイスの中の SimplePushアプリケーションの設定を見ましょう
設定はプロバイダサーバーの ホスト名と ローカルプッシュ接続が有効な Wi-FiネットワークのSSIDは
この通りです ジェーンのデバイスは Cruise Ship Wi-Fiに接続されています
連絡先です ジェーンからジョンに対して テキストメッセージを送信してみます するとジョンにはテキストメッセージが 送信されます 先に進みましょう 連絡先からジョンを選択し テキストボタンをタップします
「こんにちはジョン」と打ち込み…
送信ボタンをタップします するとジョンのデバイスには通知が 表示されます ジョンが通知をタップするとSimplePush アプリケーションのメッセージが開きます
次にジェーンがジョンに音声通話をかけます
するとジョンのデバイスには着信UIが 表示されます ジョンが通話をとると
通話が進行中であることが ご覧いただけます
ジョンが電話を切ります
以上が簡単ですが iOS 14の新機能 ローカルプッシュ接続APIを使った SimplePushアプリケーションのデモです 新しいローカルプッシュ接続APIは 2つのクラスからなります NEAppPushManagerとNEAppPushProviderです NEAppPushManagerクラスは 親アプリケーションが使用します アプリケーション拡張機能コードは NEAppPushProviderクラスのサブクラスを実装します
アプリケーション拡張機能と 親アプリケーションは 両方ともこのAPIを使ったNEAppPushProvider 権限を持っている必要があります 親アプリケーションはNEAppPushManagerクラスの インスタンスを使用して 設定を作成します その中には主にローカルプッシュ接続が 動作するWi-Fiネットワークの 情報が入っています このクラスを使って 設定をロード 保存 削除できます VoIPアプリケーションを実装するのであれば NEAppPushManagerクラスは 着信VoIP通話を取り扱う デリゲートを設定するためにも使用します アプリケーション拡張機能にはNEAppPushProvider クラスのサブクラスが実装されます このクラスは サブクラス内で オーバーライドする必要がある ライフサイクル管理メソッドを 定義します このメソッドはアプリケーション拡張機能の 起動時と終了時にシステムに呼び出されます デバイスが指定したWi-Fiネットワークに接続すると アプリケーション拡張機能が起動されます デバイスが指定したWi-Fiネットワークとの 接続を失うとシステムは アプリケーション拡張機能を停止します アプリケーション拡張機能は起動すると プロバイダサーバーとの間の ネットワーク接続を確立します そして終了時には接続を切断します VoIP通知を受け取ると アプリケーション拡張機能は このクラスを使用して システムに着信があったことを報告します それに対して システムは親アプリケーションを起動して 着信情報を渡します 設定を作成するため アプリケーションがどのように NEAppPushManagerを使用するか見てみましょう NetworkExtensionモジュールを インポートする必要があります ローカルプッシュ接続APIを使用するためです
アプリケーションプッシュプロバイダ用の設定を 作成するのは非常に簡単です
NEAppPushManagerクラスのインスタンスを 作成する必要があり それをこれらのプロパティを 設定するのに使います 対象SSIDはローカルプッシュ接続を 有効にしたいWi-Fiネットワークの SSIDの範囲を指定します
providerBundleIdentifierは アプリケーション拡張機能のバンドルIDです この設定でシステムは必要な時に アプリケーション拡張機能を実行できます
プロバイダ設定は アプリケーション拡張機能の 設定データを規定する辞書です
最後にisEnabledを 「true」に設定します ローカルプッシュ接続が この設定を使用できるようにするためです
すべての設定が終わったら saveToPreferencesメソッドを 呼び出して設定を処理します 設定の保存に成功して 有効化できたら システムはこの設定を使って ローカルプッシュ接続を有効化します アプリケーション拡張機能は NEAppPushProviderクラスを実装して 必要なメソッドをオーバーライドします
システムはstartwithcompletionHandlerを 呼び出して アプリケーション拡張機能を起動します アプリケーション拡張機能はこのメソッドの中で サーバーとの間にネットワーク接続を確立します アプリケーション拡張機能が停止した場合 システムはstopwithreasonを呼び出します アプリケーション拡張機能はこのメソッドで サーバー接続を切断します VoIP通知を受領すると アプリケーション拡張機能は reportincomingCallを呼び出して 着信VoIP通話があることを システムに報告します それに対してシステムは実行されていない場合は 親アプリケーションを起動します そして通話情報を渡します 最後のスライドにあるように アプリケーション拡張機能はVoIP着信があることを システムに報告する 責任があります それに反応して システムはアプリケーションを起動します 親アプリケーションには UIApplicationDelegateプロトコルに準拠した アプリケーションデリゲーションオブジェクトが 実装されていなくてはなりません アプリケーションプロセスが起動されたことを 知るために必要です アプリケーションは起動すると loadAllFromPreferncesを呼び出して すべての保存された設定を ロードしなくてはなりません 各NEAppPushManagerインスタンスに対して NEAppPushDelegateオブジェクトを このようにセットします
システムは親アプリケーションに対して ユーザ情報辞書を デリゲートメソッドを呼び出すことで提供します アプリケーションのメインの待ち行列上の 適切なNEAppPushManagerインスタンスに対して ユーザ情報の受領と同時に アプリケーションはCallKitに対して 着信があることを適切なCallKit APIを使い報告し 通話UIを表示します 着信の報告について 詳細は CallKit APIのドキュメントをご覧ください ほかにはSimplePushサンプルアプリケーション コードをご参照ください 着信情報を受領するには親アプリケーションは Voice over IPバックグラウンドモードを 有効にしている必要があることに ご注意ください このように Xcodeのプロジェクト特性ペーンにあります iOS 14から導入された 新しいローカルプッシュ接続APIの 詳細をご説明しました アプリケーション内で通知を使用するための 次のステップについてお話ししましょう アプリケーションにおける最も一般的な プッシュ通知の要件を満たすために PushKitまたはUserNotification フレームワークを使用する選択をすべきです ローカルプッシュ接続は APNが使用できず 通知がアプリケーションユーザにとって不可欠な ネットワーク条件でのみ 使用する必要があります
ローカルプッシュ接続がユーザにとって 正しいソリューションだと判断した場合 ローカルプッシュ接続APIを 使用するためには NEAppPushProvider権限が 必要であることをに注意してください ご視聴ありがとうございます
-
-
10:07 - Create Configuration
import NetworkExtension let manager = NEAppPushManager() manager.matchSSIDs = [ "Cruise Ship Wi-Fi", "Cruise Ship Staff Wi-Fi" ] manager.providerBundleIdentifier = "com.myexample.SimplePush.Provider" manager.providerConfiguration = [ "host": "cruiseship.example.com" ] manager.isEnabled = true manager.saveToPreferences { (error) in if let error = error { // Handle error return } // Report success }
-
11:11 - App Extension life cycle management and reporting VoIP call
// Manage App Extension life cycle and report VoIP call class SimplePushProvider: NEAppPushProvider { override func start(completionHandler: @escaping (Error?) -> Void) { // Connect to your provider server completionHandler(nil) } override func stop(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { // Disconnect your provider server completionHandler() } func handleIncomingVoIPCall(callInfo: [AnyHashable : Any]) { reportIncomingCall(userInfo: callInfo) } }
-
11:57 - Handling incoming VoIP call in the containing app
class AppDelegate: UIResponder, UIApplicationDelegate, NEAppPushDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { NEAppPushManager.loadAllFromPreferences { (managers, error) in // Handle non-nil error for manager in managers { manager.delegate = self } } return true } func appPushManager(_ manager: NEAppPushManager, didReceiveIncomingCallWithUserInfo userInfo: [AnyHashable: Any] = [:]) { // Report incoming call to CallKit and let it display call UI } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。