ユーザー通知用に iOS アプリをクライアント側の SDK と統合する (非推奨)

重要

Microsoft Graph 通知 API は非推奨になり、2022 年 1 月にデータの返送を停止しています。 別の通知エクスペリエンスについては、Microsoft Azure Notification Hubs を参照してください。 詳細については、ブログ記事「Microsoft Graph 通知 API の廃止 (ベータ版)」を参照してください。

Microsoft Entra 管理センターでアプリを登録し、パートナー デベロッパー センターでクロスデバイス エクスペリエンスをオンボードした後、次の手順は、クライアント アプリを iOS アプリ用クライアント側 SDK と統合することです。

クライアント側 SDK を使用することで、アプリは、アプリケーション サーバーから現在サインインしているユーザーを対象に発行された通知の受信を開始するために必要な登録手順を実行できるようになります。 その後で、この SDK はクライアント側での通知の管理を実行します。これには、新しい着信通知の受信、すべて消去のようなシナリオを実現するための通知状態の管理、および完全な通知履歴の取得が含まれます。

新しい着信通知のフロー

新しい受信通知を受け取ると、次の図のようなデータ フローが表示されます。

iOS アプリの新しい通知のフロー

プロセスには、いくつかのコンポーネントが含まれます:

  • アプリケーション サーバー - アプリケーションのバック エンド
  • アプリケーション クライアント: アプリケーションのフロント エンド (UWP アプリ、Android アプリ、または iOS アプリ)
  • Microsoft Graph notifications - デバイスおよびプラットフォームを跨ぐアプリケーション クライアント の異なるインスタンス間でのユーザー通知の発行と格納、同期を可能にするサービス コンポーネント
  • APNs - Apple for ios アプリによって提供される Apple プッシュ通知サービスです。 Microsoft Graph notifications は、このサービスを使用して、ユーザーの通知データの変更についてiOS アプリ クライアントに通知します。

この図は、次の手順を示しています。

  1. アプリケーションのロジック。 この手順では、ユーザーに通知を発行するトリガーになるものを取り込みます。 これは、アプリケーション固有のロジックであり、Microsoft Graph の別のもの (予定表イベントやタスクの割り当てなど) に関するイベントまたはデータの更新になることも、それとは別にアプリ サービスでユーザーに通知しようとしているものになることもあります。
  2. アプリケーション サーバーから対象ユーザーへの通知は、Microsoft Graph 通知 API 経由で発行されます。 詳細については、サーバー側との統合を参照してください。
  3. 新しい通知が含まれている Web 要求を受信すると、Microsoft Graph 通知は、このアプリとユーザーのためにクラウドで通知の内容を安全に保持します。
  4. このユーザーが通知を受け取るための各アプリケーション クライアント インスタンスのサブスクリプションには、Microsoft Graph notifications がオペレーティング システムによって提供されるネイティブ プッシュ サービスを使用して、アプリのクライアントに通知を送信します。 この例ではアプリケーションはiOS のアプリで、 [APNs バック グラウンド更新の通知] を使用して通知を送ります。
  5. 受信プッシュ通知によって通知がアプリケーションに送られた後、アプリケーションはユーザー通知ストア内の変更の取得を SDK に求めます。
  6. SDK は、Microsoft Graph 内で、ユーザー通知ストアとの安全で準拠した接続を確立します。
  7. SDK は、データの変更 (この場合は新しい通知の内容) を取得します。
  8. 変更が正常に取得された後、アプリに通知するためのイベント コールバックが SDK で発生します。
  9. アプリケーションのロジック。 この手順では、アプリがイベント コールバック内で実行する内容を取得します。 通常、ローカルのアプリデータが変更され、ローカルの UI 更新が発生します。 この場合、アプリは通常、通知の内容についてユーザーに通知する iOS アラートを構築します。

通知の更新フロー

Microsoft Graph 通知を使用する主な利点の 1 つは、通知が安全にクラウドで保持され、ステートフル リソース タイプに変更できることです。 そのため、アプリケーションはクロスデバイス シナリオにおいて、サインインしている同一のユーザーに対して、異なるデバイス間で通知の正しい状態を管理および同期できます。 あるデバイスで通知が消去または既読になったときには、その他のデバイスにリアルタイムで通知されます。 "一度処理すれば、すべての場所で消去される" ということが、ユーザーの通知体験の一部として実現されます。

次の図は、通知の状態を変更したり、一つのデバイスでの通知を削除したり、別のデバイスで状態の変更または削除を受信/処理するためのデータフローを示しています。

iOS アプリの更新通知のフロー

フローの2番目の部分の通知は、新しい受信通知の処理の流れと似ています。 これは設計上、SDK のプログラミング パターンは、アプリケーション クライアントがすべての種類のユーザー通知データの変更 (新しい受信通知、通知状態の変更、削除された通知) を同様の方法で処理できるように設計されています。

この図は、次の手順を示しています。

  1. アプリケーションのロジック。 何らかのものが、通知の変更または削除をトリガーします。 一般に、あらゆるイベントが通知を変更するトリガーになり得ます。
  2. 通知を更新または削除するクライアント SDK のアプリによる呼び出し。 現在、状態の変更に関して 2 つのプロパティ (userActionState および readState) が公開されていますが、こうした状態とその状態の更新時期はアプリケーションで定義できます。 たとえば、ユーザーが通知ポップアップを消去したときには、userActionState が消去済み (Dismissed) になるように更新します。 ユーザーが通知ポップアップをクリックして、それに対応するアプリのコンテンツを利用するアプリを起動したときに、userActionState をアクティブ化済み (Activated) に更新し、readState を読み取り (Read) に更新します。
  3. 通知を更新または削除するために対応する API が呼び出された後、SDK は、クラウド内のユーザー通知ストアに送信して、この変更をサインインしている同一ユーザーの別のアプリクライアント インスタンスに展開します。
  4. クライアントから更新/削除要求を受信した Microsoft Graph 通知は、通知ストアを更新して、この変更をサブスクライブしている別のアプリ クライアント インスタンスを特定します。
  5. 各アプリケーションの クライアント サブスクリプションには、Microsoft Graph notifications がオペレーティング システムによって提供されるネイティブ プッシュ サービスを使用して、アプリのクライアントに通知を送信します。 この例では、iOS のアプリで、 APNs バック グラウンド更新の通知を使用して通知を送ります。
  6. 受信プッシュ通知によって通知がアプリケーションに送られた後、アプリケーションはユーザー通知ストア内の変更の取得を SDK に求めます。
  7. SDK は、Microsoft Graph 内で、ユーザー通知ストアとの安全で準拠した接続を確立します。
  8. SDK によってデータが変更されます。ここでは、変更内容は通知状態の更新または通知の削除です。
  9. 変更が正常に取得された後、アプリに通知するためのイベント コールバックが SDK で発生します。
  10. アプリケーションのロジック。 この手順では、アプリがイベント コールバック内で実行する内容を取得します。 通常、ローカルのアプリデータが変更され、ローカルの UI 更新が発生します。 この場合、通知の更新があるため、アプリはローカルに UI を更新して状態の変更を反映させる必要があります。 たとえば、通知がアクティブ化されている場合、iOS 通知センター内の対応するアラート UI を削除すると、"一度処理すれば、すべての場所で消去" することができます。

Microsoft Graph 通知の詳細については、Microsoft Graph Notifications の概要を参照してください。 全てを Microsoft Graph notifications と統合するために必要な手順の詳細については、Microsoft Graph notifications の統合の概要を参照してください。

プロジェクトに SDK を追加する

Connected Devices Platform にiOS アプリを追加する最も簡単な方法は、CocoaPods 依存管理マネージャーを使用することです。 iOS プロジェクトのPodfileに移動し、次のエントリを挿入します。

platform :ios, "10.0"
workspace 'iOSSample'

target 'iOSSample' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

    pod 'ProjectRomeSdk'

  # Pods for iOSSample

注:

CocoaPodを使用するには、プロジェクトで .xcworkspace ファイルを使用する必要があります。

Connected Device Platforms の初期化

クライアント側のSDKは、Connected Device Platforms と呼ばれるインフラストラクチャの上に構築されています。 機能を使用するには、アプリ内でプラットフォームを初期化する必要があります。 この初期化手順は、通知シナリオを実行する前に必須であるため、AppDelegate メソッド内で実行する必要があります。

MCDConnectedDevicesPlatform クラスをインスタンス化して、プラットフォームを構築および初期化する必要があります。 これを行う前に、プラットフォームが起動した後、イベントが発生する可能性があるため、以下のようにイベントハンドラーを接続してください。

MCDConnectedDevicesPlatform* platform = [MCDConnectedDevicesPlatform new];
        
[platform.accountManager.accessTokenRequested subscribe:^(MCDConnectedDevicesAccountManager* _Nonnull manager, MCDConnectedDevicesAccessTokenRequestedEventArgs* _Nonnull args) {
    // implement the callback;
}];
        
[self.platform.accountManager.accessTokenInvalidated
    subscribe:^(MCDConnectedDevicesAccountManager* _Nonnull manager __unused,
        MCDConnectedDevicesAccessTokenInvalidatedEventArgs* _Nonnull request) {
    // implement the callback;
}];
        
[self.platform.notificationRegistrationManager.notificationRegistrationStateChanged subscribe:^(MCDConnectedDevicesNotificationRegistrationManager* _Nonnull manager __unused, MCDConnectedDevicesNotificationRegistrationStateChangedEventArgs* _Nonnull args) {
    // implement the callback
}];
        
[platform start];

アカウント アクセス トークンの処理

新しい着信通知のコンテンツの取得、通知状態の更新など、SDK で実行されるすべての Web 呼び出しは、ユーザーのデータに対する読み取りと書き込みになるため、常に有効なアクセス トークンが必要になります。 プラットフォームが初期化された後に、ユーザーのアクセストークンが正常に機能するために、SDK は次のイベント - アクセス トークン が要求または無効化されたときに呼び出された - の処理を必要とします。

accessTokenRequested

完全に実装するには、 iOS サンプルアプリを参照してください。

accessTokenInvalidated

完全に実装するには、 iOS サンプルアプリを参照してください。

[platform.accountManager.accessTokenInvalidated
    subscribe:^(MCDConnectedDevicesAccountManager* _Nonnull manager __unused,
        MCDConnectedDevicesAccessTokenInvalidatedEventArgs* _Nonnull request) {
}];

プッシュ登録の有効期限を処理する

Microsoft Graph notifications は、Apn、iOSのネイティブのプッシュ プラットフォームを使用して、ユーザー通知のデータ変更をクライアント アプリケーションに通知します。 これは、新しい受信通知がアプリサーバーから発行されている場合、またはクロスデバイス シナリオにおいてサインインした同じユーザーの別のデバイスで通知の状態が更新された場合に発生します。

このような理由から、バックグラウンドでの更新通知を正常に受信するための有効な APNs トークンが必要です。 次のイベントコールバックでは、APNs プッシュトークンの有効期限を処理します。

notificationRegistrationStateChanged

完全に実装するには、 iOS サンプルアプリを参照してください。

ユーザーにサインインする

Microsoft Graph通知は、その他の Microsoft Graph の多くのリソース タイプと同様に、ユーザーが中心になります。 アプリでサブスクライブし、サインインしたユーザーへの通知を受信できるようにするには、最初に登録プロセスで使用する有効な OAuth トークンを入手する必要があります。 OAuth トークンを生成および管理する方法を選択できます。 サンプル アプリでは ADAL を使用します。

Microsoft アカウント を使用している場合は、サインイン リクエストに次の許可を含める必要があります:wl.offline_access", ccs.ReadWrite, wns.connect, asimovrome.telemetry, https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp

Microsoft Entra アカウントを使用している場合は、次の対象ユーザーを要求する必要があります。 https://cdpcs.access.microsoft.com

プラットフォームにユーザーアカウントを追加する

サインインしたユーザーアカウントを SDK に登録する必要があります。 これは、アカウントの追加と、 APN を通じて初期通知を受信するプッシュチャネルの登録を伴います。 詳細については、サンプルのprepareAccountAsync メソッドを参照してください。

MCDConnectedDevicesPlatform* platform = [MCDConnectedDevicesPlatform new];
MCDConnectedDevicesAccount* mcdAccount = [MCDConnectedDevicesAccount new];

[platform.accountManager addAccountAsync:mcdAccount callback:adapter]; 

ユーザーの通知を受信するためのサブスクライブ

このサインインしているユーザーのアプリケーション用に、UserDataFeed オブジェクトをインスタンス化する必要があります。 アプリケーションは、クロスデバイス エクスペリエンスの開始時に指定したクロスプラットフォーム アプリ ID によって識別されます。

// Initialize the feed and subscribe for notifications
MCDUserDataFeed* feed = [MCDUserDataFeed getForAccount:account
                        platform:platform
                        activitySourceHost:APP_HOST_NAME];

NSArray<MCDUserDataFeedSyncScope*>* syncScopes = @[ [MCDUserNotificationChannel syncScope] ];
[feed subscribeToSyncScopesAsync:syncScopes
        callback:^(BOOL success __unused, NSError* _Nullable error __unused) {
    // Start syncing down notifications
    [feed startSync];
}];

ユーザー通知を受信および管理する

このトピックの前半のフロー図では、アプリ サーバーからの新しい着信通知や、別のアプリケーション クライアント インスタンスで開始された通知の更新または削除を処理するためのプログラミング パターンを示しました。 このようなデータの変更を処理する手順は次のとおりです。

着信プッシュ通知シグナルの処理

全ての種類のユーザー通知データの変更について、プッシュ通知としてアプリクライアントに配信されるシグナルが生成されます。 iOS アプリの場合、シグナルは APNs バックグラウンド更新通知として配信されます。 データ メッセージ シグナルを受信するには、アプリがTryParseを呼び出し、実際のデータ変更のためのSDKによる Microsoft Graph notifications サービスからの取得をトリガーします。

// App running in background and received a push notification, launched by user tapping the alert view
MCDConnectedDevicesNotification* notification = [MCDConnectedDevicesNotification tryParse:notificationInfo];
if (notification != nil) {
    [_platformManager.platform processNotificationAsync:notification
            completion:^(NSError* error __unused) {
        // NOTE: it may be useful to attach completion to this async in order to know when the
        // notification is done being processed.
        // This would be a good time to stop a background service or otherwise cleanup.
    }];
} else {
    NSLog(@"Remote notification is not for ConnectedDevicesPlatform, skip processing");
}

ユーザー通知のデータ変更の処理

SDK によってデータ変更が正常にフェッチされると、イベント コールバックが呼び出され、アプリ クライアントによる通知の作成、更新、または削除の処理が求められます。

[reader readBatchAsyncWithMaxSize:100 completion:^(NSArray<MCDUserNotification *> * _Nullable notifications,
                                                    NSError * _Nullable error) {
    if (error) {
    } else {
        for (MCDUserNotification* notification in self.notifications) {
        // Handle notification change based on change type;
        }
        }
    }
}];

通知の更新状態

このアプリクライアントインスタンスから通知状態が変更された場合 (たとえば、このデバイスのトースト通知ポップアップがユーザーによって有効化された場合)、アプリは 同じユーザーが使用する全てのデバイスでこの状態の変更を同期するために、SDK を呼び出して通知の状態を更新する必要があります。

- (void)dismissNotification:(MCDUserNotification*)notification {
    if (notification.userActionState == MCDUserNotificationUserActionStateNoInteraction) {
        [self dismissNotificationFromTrayWithId:notification.notificationId];
        notification.userActionState = MCDUserNotificationUserActionStateDismissed;
        [notification saveAsync:^(__unused MCDUserNotificationUpdateResult * _Nullable result, __unused NSError * _Nullable error) {
        // handle result;
         }];
    }
}

通知を削除する

このアプリクライアントインスタンスから通知の削除が行われた場合 (たとえば、この通知に対応するタスクが完了とマークされ、アプリのデータベースから削除された場合)、アプリは同じユーザーが使用する全てのデバイスでこの削除の操作を同期するために、SDK を呼び出して通知を削除する必要があります。

通知は、有効期限が切れているか、明示的に削除された場合にのみ、ユーザー通知ストアから削除されます。 UserActionState のセマンティック定義はアプリケーション自体によって定義されているため、UserActionState が消去済み (Dismissed) になるように更新しても、ユーザー通知は削除されません。

- (void)deleteNotification:(MCDUserNotification*)notification {
    [_channel deleteUserNotificationAsync:notification.notificationId
     completion:^(__unused MCDUserNotificationUpdateResult* _Nullable result, NSError* _Nullable error) {
        // handle result;
     }];
}