WWDC Quick Look 💓 By SwiftGGTeam
Build local push connectivity for restricted networks

Build local push connectivity for restricted networks

元の動画を見る

ハイライト

iOS 14 のローカル プッシュ接続により、App Extension が指定された Wi-Fi ネットワーク上のローカル プロバイダー サーバーに直接接続できるため、APN やインターネット接続がない環境でもテキスト通知や VoIP 通話を受信できます。

主要内容

プッシュ通知は通常、Apple プッシュ通知サービス (APN) に依存します。プロバイダー サーバーはペイロードを APN に送信し、APN はそれをターゲット デバイスに送信します。アプリは PushKit または UserNotifications を通じてそれを受け取ります。このモデルは電力を節約し、ほとんどのネットワーク シナリオに適しています。

この問題は、APN が到達できないネットワークで発生します。逐語的に示されている例としては、クルーズ船、航空会社、キャンプ場、病院などがあります。これらの場所にはインターネットがないか、インターネット接続が限られている場合がありますが、それでもアプリ内のメッセージ、通話、およびオンサイトのコラボレーションはタイムリーに届く必要があります。ローカル サーバーへのポーリングを継続すると電力が無駄になり、ユーザーに安定した通話エクスペリエンスを提供することが困難になります。

iOS 14 のローカル プッシュ接続では、このリンクが LAN 内での直接通信に変更されます。アプリは、ローカル プッシュに対してどの Wi-Fi SSID を有効にする必要があるかを宣言します。デバイスがこれらの Wi-Fi に接続すると、システムはアプリ拡張機能を開始します。拡張機能は、ローカル プロバイダー サーバーに接続し、開発者独自のプロトコルに従って通知を受信する役割を果たします。デバイスがこれらの Wi-Fi から離れると、システムは拡張機能を停止します。

この機能は APN に代わるものではありません。 Apple はセッション内で、通常のプッシュでは引き続き PushKit または UserNotifications を使用することを明確に推奨しています。ローカル プッシュ接続は、ユーザーにとって通知が重要であり、ネットワーク環境が APN へのアクセスを許可していない、少数のシナリオを対象としています。これを採用するには、NEAppPushProvider 資格を申請する必要があり、含まれるアプリとアプリ拡張機能の両方がこの資格を持っている必要があります。

SimplePush アプリのデモはクルーズ船に設置されています。ジェーンとジョンのデバイスにはインターネットがなく、「クルーズ船 Wi-Fi」にのみ接続されています。ジェーンがテキスト メッセージを送信すると、ジョンのデバイスはローカル通知を受信します。ジェーンが音声通話を開始すると、ジョンのデバイスにはシステムの着信インターフェイスが表示されます。このデモは、ローカル プッシュの 2 つの出口に対応しています。ユーザーに表示される通知はローカル通知を経由し、着信 VoIP 通話は拡張機能によってシステムに報告され、それを含むアプリと CallKit に渡されます。

詳細

1. 含まれるアプリでローカル プッシュ構成を作成する

10:07NEAppPushManager含まれるアプリによって使用されます。ターゲット Wi-Fi、拡張バンドル ID、拡張に渡されるカスタム構成、有効化ステータスなど、ローカル プッシュ接続の構成が保存されます。

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
}

キーポイント:

  • import NetworkExtensionLocal Push Connectivity が配置されているフレームワークを紹介します。 -NEAppPushManager()構成オブジェクトを作成すると、それを含むアプリがその保存と管理を行います。 -matchSSIDsローカル プッシュを有効にする Wi-Fi ネットワークを指定すると、デバイスがこれらのネットワークに参加した場合にのみ拡張機能が起動されます。 -providerBundleIdentifier実装を指すNEAppPushProviderアプリの拡張機能。 -providerConfigurationセッション例で使用される、ホストなどの構成データを拡張機能に渡します。cruiseship.example.com
  • isEnabled = trueこの構成が保存後に有効になることを示します。 -saveToPreferences構成をシステム環境設定に書き込みます。システムは、保存が成功し、構成が有効になった後にのみ、ローカル プッシュ接続を有効にします。

2. App Extension で接続ライフサイクルを管理する

(11:11) アプリ拡張機能の実装NEAppPushProviderサブクラス。デバイスが一致する Wi-Fi に参加するとシステムによって呼び出されますstart、デバイスがこれらの Wi-Fi から離れるときに呼び出されますstop。拡張機能は、これら 2 つのエントリでローカル プロバイダー サーバー接続を確立および切断します。

// 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)
    }
}

キーポイント:

  • SimplePushProvider継承するNEAppPushProvider、前の構成のプロバイダー拡張機能に対応します。 -start(completionHandler:)これは拡張機能の起動エントリであり、プロバイダー サーバーへの接続を確立するのに適しています。 -completionHandler(nil)起動プロセスが完了したことをシステムに伝えます。 -stop(with:completionHandler:)これは、サーバーの切断とステータスのクリーンアップに適した拡張停止エントリです。 -handleIncomingVoIPCallここで、サンプル アプリが VoIP ペイロード自体を処理します。 -reportIncomingCall(userInfo:)着信情報をシステムに報告すると、システムはそれを含むアプリを起動してユーザー情報を提供します。

ローカル プッシュのプロトコル層は、アプリとプロバイダー サーバー自体によって定義されます。逐語的なドラフトでは、拡張機能がローカル Wi-Fi ネットワーク上のサーバーと直接通信する必要があるとのみ記載されており、ペイロード形式は指定されていません。実装を記述するときは、プロトコル解析、再接続戦略、およびエラー報告を拡張機能内に配置する必要があります。ユーザー指向のリマインダーは、システム通知または CallKit に引き渡される必要があります。

3. 含まれるアプリで VoIP 通話情報を受信する

(11:57) 内線が VoIP 通話の着信を報告すると、システムはそれを含むアプリを起動します。アプリ起動時にセーブデータをロードするNEAppPushManager、マネージャーごとに設定されますNEAppPushDelegate、受け取るためにdidReceiveIncomingCallWithUserInfo折り返し電話。

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
    }
}

キーポイント:

  • AppDelegate同時に遵守するUIApplicationDelegateそしてNEAppPushDelegate
  • loadAllFromPreferencesシステムに保存されているローカル プッシュ構成を読み取ります。 -manager.delegate = selfコールバックを包含アプリに接続し直します。 -didReceiveIncomingCallWithUserInfo拡張機能によって報告されたユーザー情報をメイン キューに配信します。
  • 着信を報告し、システムの着信 UI を表示するには、コールバックで CallKit を使用する必要があります。
  • 逐語的には、着信情報を受信するには、含まれるアプリで Xcode 機能の Voice over IP バックグラウンド モードを有効にする必要があることも思い出させます。

4. ユーザーに表示される通知と VoIP 通知は異なる出口を通過します

(05:07) 拡張機能は、ユーザーに表示されるテキスト メッセージを受信した後、UserNotifications フレームワークを使用してローカル通知を作成する必要があります。通常のプッシュ通知を受信するのと同じように、アラートの表示、サウンドの再生、バッジの更新が可能で、ユーザーはアプリにアクセスできるようになります。

User-facing notification path:
provider server -> NEAppPushProvider extension -> UserNotifications local notification

VoIP notification path:
provider server -> NEAppPushProvider extension -> reportIncomingCall(userInfo:) -> containing app -> CallKit

キーポイント:

  • テキスト メッセージなどのユーザー向け通知は、ユーザーの注意を引くためにローカル通知を使用します。
  • VoIP 通知には着信情報が含まれ、内線パスが伝えられます。reportIncomingCall(userInfo:)システムに報告します。
  • システムは、含まれているアプリを起動し、通話情報を引き渡す責任があります。NEAppPushDelegate
  • 含まれているアプリは、CallKit を通じて着信通話 UI を表示し、システム通話との一貫性を保ちます。

重要ポイント

1. 船舶、公園、病院のオフラインメッセージングシステム

機能: ローカル Wi-Fi にのみアクセスできる会場にインスタント メッセージングとアラートを提供します。

実行する価値がある理由: これはまさにセッションのターゲット シナリオです。 APN に到達できない場合でも、デバイスは通過できますNEAppPushProviderローカルプロバイダーサーバーに接続します。

開始方法: まず NEAppPushProvider 資格を申請します。含まれるアプリで使用するNEAppPushManager.matchSSIDs限られた場所での Wi-Fi。拡張機能は、テキスト ペイロードを受信した後、UserNotifications を使用してローカル通知を送信します。

2. LAN VoIP 通話入口

対処方法: 同じ制限付きネットワーク上のユーザーが相互に音声通話を開始し、システムの着信通話 UI を使用できるようにします。

実行する価値がある理由: インターネットなしのクルーズ船 Wi-Fi で着信通話 UI を表示する SimplePush の逐語的なデモンストレーション。

開始方法: VoIP ペイロードを受信した後に内線が呼び出されますreportIncomingCall(userInfo:);アプリの実装を含むNEAppPushDelegate;コールバックを受信したら、着信通話を CallKit に渡し、Voice over IP バックグラウンド モードを有効にします。

3. 固定 SSID のローカル サービス設定ページ

対処方法: アプリ設定ページでローカル プッシュを有効にするサーバー ホストと Wi-Fi 名を保存します。

実行する価値がある理由: セッションの例では、プロバイダー サーバーのホストと SSID を SimplePush 設定に設定します。構成が明確になって初めて、システムは拡張機能をいつ開始するかを認識します。

開始方法: ユーザーが選択した、または管理者が発行した SSID を書き込みますmatchSSIDs;サーバーホストを入れますproviderConfiguration;保存時にチェックsaveToPreferencesエラーが発生し、回復可能なプロンプトが表示されます。

4. APN とローカル プッシュのダウングレード戦略

対処方法: インターネットに接続しているときは APN を引き続き使用し、指定された制限付き Wi-Fi に入った後はローカル プッシュを有効にします。

実行する価値がある理由: Apple は、ほとんどの通知で引き続き PushKit または UserNotifications を使用することを推奨しています。ローカル プッシュは、APN に到達できず、通知が必要なシナリオにのみ対応します。

開始方法: APN リンク内の通常のリモート プッシュ ロジックを維持します。使用NEAppPushManagerローカルにプッシュする必要がある SSID のみを宣言します。拡張プロトコルで十分なメッセージ タイプを伝送できるため、テキスト通知と VoIP 通話はそれぞれローカル通知と CallKit を経由します。

関連セッション

コメント

GitHub Issues · utterances