次の方法で共有


iOS 用のユーザー アクティビティの実装

ユーザー アクティビティは、アプリケーション内のユーザーのタスクを表すデータコンストラクトです。 現在のタスクのスナップショットを保存して、後で続行できるようにします。 Windows タイムライン機能は、テキストとグラフィックスを含むカードとして表される、最近のすべてのアクティビティのスクロール可能なリストを Windows ユーザーに表示します。 ユーザー アクティビティ全般の詳細については、「 デバイス間でもユーザー アクティビティを続行する」を参照してください。 アクティビティを作成または更新するタイミングに関する推奨事項については、 ユーザー アクティビティのベスト プラクティス ガイドを参照してください。

Project Rome SDK を使用すると、iOS アプリは、タイムラインなどの Windows 機能で使用するユーザー アクティビティを発行できるだけでなく、エンドポイントとして機能し、タイムラインと同様にアクティビティをユーザーに読み取り戻すこともできます。 これにより、クロスデバイス アプリはプラットフォームを完全に超越し、デバイスではなくユーザーに従うエクスペリエンスを提示できます。

Project Rome の機能は、Connected Devices Platform と呼ばれる基になるプラットフォームでサポートされています。 このガイドでは、Connected Devices Platform の使用を開始するために必要な手順と、プラットフォームを使用してユーザー アクティビティに関連する機能を実装する方法について説明します。

以下の手順では、GitHub で入手できる Project Rome iOS サンプル アプリ のコードを参照します。

これらのシナリオに関連するリファレンス ドキュメントへのリンクについては、 API リファレンス ページを参照してください。

接続デバイス プラットフォームと通知の設定

アプリを登録する

Project Rome SDK のほぼすべての機能 (近くの共有 API の例外) には、Microsoft アカウント (MSA) または Azure Active Directory (AAD) 認証が必要です。 MSA をまだお持ちでなく、MSA を使用する場合は、 account.microsoft.com に登録します。

Azure Active Directory (AAD) アカウントは、Device Relay API ではサポートされていません。

選択した認証方法を使用して、 アプリケーション登録ポータルの手順に従って、アプリを Microsoft に登録する必要があります。 Microsoft 開発者アカウントをお持ちでない場合は、作成する必要があります。

MSA を使用してアプリを登録する場合は、クライアント ID 文字列を受け取る必要があります。 後で使用するために保存します。 これにより、アプリは Microsoft の Connected Devices Platform リソースにアクセスできるようになります。 AAD を使用している場合は、クライアント ID 文字列を取得する手順については、 Azure Active Directory 認証ライブラリ を参照してください。

SDK を追加する

iOS アプリに Connected Devices Platform を追加する最も簡単な方法は、 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 ファイルを使用する必要があります。

認証とアカウント管理を設定する

接続デバイス プラットフォームでは、登録プロセスで有効な OAuth トークンを使用する必要があります。 OAuth トークンを生成して管理する好みの方法を使用できます。 ただし、開発者がプラットフォームの使用を開始できるように、アプリで更新トークンを生成および管理するために使用できる iOS サンプル アプリ の一部として認証プロバイダーが含まれています。

指定されたコードを使用しない場合は、 MCDConnectedDevicesAccountManager インターフェイスを自分で実装する必要があります。

MSA を使用している場合は、サインイン要求に、 "wl.offline_access""ccs.ReadWrite""dds.read""dds.register""wns.connect""asimovrome.telemetry""https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp"のスコープを含めます。

Azure Active Directory (AAD) アカウントは、Device Relay API ではサポートされていません。

AAD アカウントを使用している場合は、 "https://cdpcs.access.microsoft.com""https://cs.dds.microsoft.com""https://wns.windows.com/""https://activity.microsoft.com"の対象ユーザーを要求する必要があります。

提供された MCDConnectedDevicesAccountManager 実装を使用するかどうかにかかわらず、AAD を使用している場合は、Azure portal でのアプリの登録で次のアクセス許可を指定する必要があります (Azure Active Directory > アプリの登録 portal.azure.com >)。

  • Microsoft アクティビティ フィード サービス
    • このアプリのユーザー通知を配信および変更する
    • ユーザーのアクティビティ フィードへのアプリのアクティビティの読み取りと書き込み
  • Windows 通知サービス
    • デバイスを Windows Notification Service に接続する
  • Microsoft Device Directory Service
    • デバイスの一覧を表示する
    • デバイスとアプリの一覧に追加する
  • Microsoft Command Service
    • ユーザーのデバイスとの通信
    • ユーザー デバイスの読み取り

アプリケーションをプッシュ通知に登録する

Apple プッシュ通知のサポートのために、Apple にアプリケーションを登録します。 後で必要になるので、受信した送信者 ID とサーバー キーを必ずメモしておいてください。

登録したら、プッシュ通知機能をアプリの接続済みデバイス プラットフォームに関連付ける必要があります。

self.notificationRegistration = [[MCDConnectedDevicesNotificationRegistration alloc] init];
    if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications])
    {
        self.notificationRegistration.type = MCDNotificationTypeAPN;
    }
    else
    {
        self.notificationRegistration.type = MCDNotificationTypePolling;
    }
    self.notificationRegistration.appId = [[NSBundle mainBundle] bundleIdentifier];
    self.notificationRegistration.appDisplayName = (NSString*)[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
    self.notificationRegistration.token = deviceToken;
    self.isRegisteredWithToken = YES;

クロスデバイス エクスペリエンスのために Microsoft Windows デベロッパー センターにアプリを登録する

Warnung

この手順は、Project Rome 機能を使用して Windows 以外のデバイスからデータにアクセスしたり、要求したりする場合にのみ必要です。 Windows デバイスのみを対象とする場合は、この手順を完了する必要はありません。

Microsoft 開発者ダッシュボードのクロスデバイス エクスペリエンス機能にアプリを登録します。 これは、上記の MSA と AAD アプリの登録とは異なる手順です。 このプロセスの主な目標は、プラットフォーム固有のアプリ ID を、Connected Devices Platform によって認識されるクロスプラットフォーム アプリ ID にマップすることです。 この手順では、アプリが利用するモバイル プラットフォームに対応するネイティブ プッシュ通知サービスを使用した通知の送信も有効になります。 iOS の場合、APNS - Apple Push Notification Service を介して iOS アプリ エンドポイントに通知を送信できます。

デベロッパー センター ダッシュボードに移動し、左側のナビゲーション ウィンドウから [クロスデバイス エクスペリエンス] に移動し、新しいクロスデバイス アプリの構成を選択します。 デベロッパー センター ダッシュボード - クロスデバイス エクスペリエンス

デベロッパー センターのオンボーディング プロセスには、次の手順が必要です。

  • サポートされているプラットフォームを選択します。アプリがプレゼンスを持ち、クロスデバイス エクスペリエンスが有効になるプラットフォームを選択します。 Graph 通知の統合の場合は、使用しているプラットフォームに応じて、Windows、Android、iOS から選択できます。 クロスデバイス エクスペリエンス - サポートされているプラットフォーム

  • アプリ ID を提供する - 使用しているプラットフォームごとにアプリ ID を提供します。 iOS アプリの場合、これはプロジェクトの作成時にアプリに割り当てたパッケージ名です。 プラットフォームごとに異なる ID (最大 10 個) を追加できることに注意してください。これは、同じユーザーを対象とするアプリ サーバーから送信された同じ通知を受信できるように、同じアプリの複数のバージョンまたは異なるアプリがある場合です。 クロスデバイス エクスペリエンス – アプリ ID

  • 上記の MSA/AAD アプリ登録手順で取得した MSA または AAD アプリの登録からアプリ ID を指定または選択します。 クロスデバイス エクスペリエンス – MSA と AAD アプリの登録

  • アプリに関連するネイティブ通知プラットフォーム (Windows の場合は WNS、Android の場合は FCM、iOS の場合は APNS) の資格情報を入力して、ユーザーを対象とした通知を発行するときにアプリ サーバーから通知を配信できるようにします。 クロスデバイス体験 – プッシュ認証情報

  • 最後に、クロスデバイス アプリ ドメインを確認して、アプリがドメインの所有権を持ち、それをアプリのクロスデバイス ID として使用できることを確認します。 クロスデバイス エクスペリエンス – ドメイン検証

プラットフォームの使用

プラットフォームのインスタンスを作成する

開始するには、プラットフォームをインスタンス化するだけです。

MCDConnectedDevicesPlatform* platform = [MCDConnectedDevicesPlatform new];

MCDConnectedDevicesAccountManager をサブスクライブする

プラットフォームでは、認証されたユーザーがプラットフォームにアクセスする必要があります。 有効なアカウントが使用されていることを確認するには、 MCDConnectedDevicesAccountManager イベントをサブスクライブする必要があります。

[MCDConnectedDevicesPlatform* platform.accountManager.accessTokenRequested
     subscribe:^(MCDConnectedDevicesAccountManager* _Nonnull manager __unused,
                 MCDConnectedDevicesAccessTokenRequestedEventArgs* _Nonnull request __unused) {

                    // Get access token

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

                      // Refresh and renew existing access token

                 }

MCDConnectedDevicesNotificationRegistrationManager をサブスクライブする

同様に、プラットフォームでは通知を使用してデバイス間でコマンドを配信します。 そのため、 MCDConnectedDevicesNotificationRegistrationManager イベントをサブスクライブして、クラウド登録の状態が使用されているアカウントに対して有効であることを確認する必要があります。 MCDConnectedDevicesNotificationRegistrationState を使用して状態を確認する

[MCDConnectedDevicesPlatform* platform.notificationRegistrationManager.notificationRegistrationStateChanged
     subscribe:^(MCDConnectedDevicesNotificationRegistrationManager* manager __unused,
                 MCDConnectedDevicesNotificationRegistrationStateChangedEventArgs* args __unused) {

                     // Check state using MCDConnectedDevicesNotificationRegistrationState enum

                 }

プラットフォームを起動する

プラットフォームが初期化され、イベント ハンドラーが配置されたので、リモート システム デバイスの検出を開始する準備ができました。

[MCDConnectedDevicesPlatform* platform start];

アプリに既知のユーザー アカウントを取得する

アプリに認識されているユーザー アカウントの一覧が MCDConnectedDevicesAccountManager と正しく同期されていることを確認することが重要です。

MCDConnectedDevicesAccountManager.addAccountAsync を使用して、新しいユーザー アカウントを追加します。

[MCDConnectedDevicesPlatform* platform.accountManager
     addAccountAsync:self.mcdAccount
     callback:^(MCDConnectedDevicesAddAccountResult* _Nonnull result, NSError* _Nullable error) {

     // Check state using **MCDConnectedDevicesAccountAddedStatus** enum

     }

無効なアカウントを削除するには、MCDConnectedDevicesAccountManager.removeAccountAsync を使用できます。

 [MCDConnectedDevicesPlatform* platform.accountManager
     removeAccountAsync:existingAccount
     callback:^(MCDConnectedDevicesRemoveAccountResult* _Nonnull result __unused, NSError* _Nullable error) {

                    // Remove invalid user account

     }

ユーザー アクティビティ チャンネルを初期化する

アプリにユーザー アクティビティ機能を実装するには、まず MCDUserActivityChannel を作成してユーザー アクティビティ フィードを初期化する必要があります。 これは、上記のプラットフォーム初期化手順と同様に扱う必要があります。アプリがフォアグラウンドに来るたびに (ただし、プラットフォームの初期化前には) チェックを行い、場合によってはやり直す必要があります。

この手順には、サインインしているユーザー アカウントが必要です。 上記のように、認証プロバイダーサンプルのクラスを使用して、MCDUserAccount を簡単に取得できます。 また、Microsoft 開発者ダッシュボードの登録を通じて取得されたクロスプラットフォーム アプリ ID も必要です。 サンプル アプリの次のメソッドは、MCDUserActivityChannel を初期化します。

サンプル アプリの次のメソッドは、MCDUserActivityChannel を初期化します。


    // Get a UserActivity channel, getting the default channel        
    NSLog(@"Creating UserActivityChannel");
    NSArray<MCDUserAccount*>* accounts = [[AppDataSource sharedInstance].accountProvider getUserAccounts];
    MCDUserDataFeed* userDataFeed = [MCDUserDataFeed userDataFeedForAccount:accounts[0]
        platform:[AppDataSource sharedInstance].platform
        activitySourceHost:CROSS_PLATFORM_APP_ID];
    NSArray<MCDSyncScope*>* syncScopes = @[ [MCDUserActivityChannel syncScope] ];
    [userDataFeed addSyncScopes:syncScopes];
    self.channel = [MCDUserActivityChannel userActivityChannelWithUserDataFeed:userDataFeed];
}
else
{
    NSLog(@"Must have an active account to publish activities!");
    self.createActivityStatusField.text = @"Need to be logged in!";
}

この時点で、チャネルには MCDUserActivityChannel の参照が含まれている必要があります。

ユーザーアクティビティを作成して公開する

次のサンプル コードは、新しい MCDUserActivity インスタンスの作成方法を示しています。

- (IBAction)createActivityButton:(id)sender
{
    // Step #2: Create a UserActivity
    [self.channel getOrCreateUserActivityAsync:[[NSUUID UUID] UUIDString]
        completion:^(MCDUserActivity* activity, NSError* error) {
            if (error)
            {
                NSLog(@"%@", error);
                self.createActivityStatusField.text = @"Error creating activity!";
            }
            else if (!activity)
            {
                NSLog(@"No activity created!");
            }
            else
            {
                dispatch_async(dispatch_get_main_queue(), ^{
                    self.activity = activity;

                    // Create an activityId so the app knows so you know how to get back
                    self.activityId.text = activity.activityId;
                    self.createActivityStatusField.text = @"Created by iOSSample";
                    // Create a deep link so the app can get right back to where it was
                    self.activationUri.text = @"roman-app:";
                    self.createActivityStatusField.text = @"Activity created";
                });
            }
        }];
}

次のメソッドでは、アクティビティが発行される前に MCDUserActivity のビジュアル データが設定されます。 アクティブ化 URI は、アクティビティがアクティブ化されたときに実行されるアクションを決定します (タイムラインで選択されている場合など)。 他のデバイスでアクティビティを表示すると、表示テキストが表示されます (Windows タイムラインなど)。 iconUri は、アイコン画像への Web リンクです。

- (IBAction)publishActivityButton:(id)sender
{
    self.createActivityStatusField.text = @"Saving";
    self.activity.activationUri = self.activationUri.text;
    // Set the display text for your activity.
    self.activity.visualElements.displayText = @"Visual Element, like an Adaptive Card";
    self.activity.visualElements.attribution.iconUri = @"https://www.microsoft.com/favicon.ico";

    // ...

MCDUserActivity にこのデータが設定されると、発行操作が行われます。

    // ...

    // Publish the Activity
    [self.activity saveAsync:^(NSError* error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error)
            {
                NSLog(@"%@", error);
                self.createActivityStatusField.text = @"Error saving activity";
            }
            else
            {
                self.createActivityStatusField.text = @"Saved successfully!";
                [self.sessionButton setTitle:@"Start Session" forState:normal];
            }
        });
    }];
}

mActivityId = UUID.randomUUID().toString();
mDisplayText = "Created by OneSDK Sample App";
mActivationUri = "http://contoso.com");

ヒント

上記のプロパティに加えて、構成できる他の多くの機能があります。 UserActivity をカスタマイズするさまざまな方法の詳細については、MCDUserActivity、MCDUserActivityVisualElementsおよび MCDUserActivityAttribution クラスを参照してください。 ユーザー アクティビティの設計方法に関する詳細な推奨事項については、 ユーザー アクティビティのベスト プラクティス ガイドを参照してください。

既存のユーザー アクティビティを更新する

既存のアクティビティがあり、その情報を更新する場合 (新しいエンゲージメントや変更されたページなどが発生した場合)、 MCDUserActivitySession を使用して更新できます。

セッションを作成すると、アプリは UserActivity のプロパティに必要な変更を加えることができます。 変更が完了したら、セッションを閉じます。

サンプル アプリの次のメソッドは、セッションのオンとオフを切り替えます。

- (IBAction)manageSessionButton:(id)sender
{

    // Start a new a session for the UserActivity
    if (self.session == nil)
    {
       self.session = [self.activity createSession];
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"UserActivitySession has started %@", self.session);
            self.session = [self.activity createSession];
            dispatch_async(dispatch_get_main_queue(), ^{ [self.sessionButton setTitle:@"Stop Session" forState:normal]; });
        });
    }
    else
    {
        // Stop the UserActivitySession
        [self.session close];
        self.session = nil;
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"UserActivitySession has stopped %@", self.session);
            [self.sessionButton setTitle:@"Start Session" forState:normal];
        });
    }
}

MCDUserActivitySession は、MCDUserActivitySessionHistoryItem を作成する方法と考えることができます (次のセクションで説明します)。 ユーザーが新しいページに移動するたびに新しい MCDUserActivity を 作成するのではなく、ページごとに新しいセッションを作成するだけです。 これにより、より直感的で整理されたアクティビティの読み取りエクスペリエンスが実現します。

ユーザー アクティビティの読み取り

アプリでは、Windows タイムライン機能と同様に、ユーザー アクティビティを読み取ってユーザーに表示できます。 ユーザー アクティビティの読み取りを設定するには、以前と同じ MCDUserActivityChannel インスタンスを使用します。 このインスタンスは MCDUserActivitySessionHistoryItem インスタンスを公開できます。これは、特定の期間中の特定のアクティビティにおけるユーザーの関与を表します。

- (IBAction)readActivityButton:(id)sender
{

    // Read/sync your UserActivities
    [self.channel getRecentUserActivitiesAsync:(NSInteger)5
        completion:^(NSArray<MCDUserActivitySessionHistoryItem*>* _Nonnull result, NSError* _Nullable error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (error)
                {
                    self.readActivityStatusField.text = @"Error reading activity!";
                }
                else if (result.count == 0)
                {
                    self.readActivityStatusField.text = @"Read completed, no activities returned";
                }
                else
                {
                    self.readActivityStatusField.text = @"Read completed!";
                    MCDUserActivitySessionHistoryItem* item = result.firstObject;
                    self.activityList.text = item.userActivity.activityId;
                    self.activityDisplay.text = item.userActivity.visualElements.displayText;
                }
            });
        }];
}

これで、アプリに MCDUserActivitySessionHistoryItemの一覧が設定されているはずです。 これらのそれぞれは、基になる MCDUserActivity を配信できます (詳細については MCDUserActivitySessionHistoryItem を参照)、ユーザーに表示できます。