Xamarin.iOS での SiriKit の実装

この記事では、Xamarin.iOS アプリで SiriKit サポートを実装するために必要な手順について説明します。

iOS 10 の新機能である SiriKit を使用すると、Xamarin.iOS アプリは、Siri と iOS デバイス上の Maps アプリを使用してユーザーがアクセスできるサービスを提供できます。 この記事では、Xamarin.iOS アプリで SiriKit サポートを実装するために必要な手順について説明します。これには、必要な意図拡張機能、意図 UI 拡張機能、ボキャブラリを追加します。

Siri は、関連するタスクの既知のアクションのグループ であるドメインの概念に対応しています。 アプリが Siri とやり取りするたびに、次のように既知のサービスドメインのいずれかに分類される必要があります。

  • オーディオまたはビデオ通話。
  • 乗車を予約する。
  • ワークアウトの管理。
  • メッセージング。
  • 写真の検索。
  • 支払いの送受信。

ユーザーがアプリ拡張機能のサービスの 1 つに関係する Siri の要求を行うと、SiriKit は拡張機能に、ユーザーの要求とサポート データを記述する Intent オブジェクトを送信します。 その後、アプリ拡張機能は、指定された意図に対して適切な Response オブジェクトを生成し、拡張機能が要求を処理する方法を詳しく説明します。

このガイドでは、SiriKit のサポートを既存のアプリに含む簡単な例を紹介します。 この例のために、偽の MonkeyChat アプリを使用します。

MonkeyChat アイコン

MonkeyChat は、ユーザーの友人の独自の連絡先ブックを保持し、それぞれが画面名 (Bobo など) に関連付け、ユーザーが画面名で各友人にテキスト チャットを送信できるようにします。

SiriKit を使用したアプリの拡張

「SiriKit の概念を理解する」ガイドに示すように、SiriKit を使用したアプリの拡張には、次の 3 つのメイン部分があります。

SiriKit を使用したアプリの拡張図

これには以下が含まれます。

  1. 意図拡張機能 - ユーザーの応答を検証し、アプリが要求を処理できることを確認し、ユーザーの要求を満たすためにタスクを実際に実行します。
  2. 意図 UI 拡張機能 - オプション。Siri 環境の応答にカスタム UI を提供し、アプリの UI とブランド化を Siri に取り込んで、ユーザーのエクスペリエンスを強化できます。
  3. アプリ - Siri の操作を支援するために、ユーザー固有の語彙をアプリに提供します。

これらの要素とアプリに含める手順については、以下のセクションで詳しく説明します。

アプリの準備

SiriKit は拡張機能に基づいて構築されていますが、拡張機能をアプリに追加する前に、開発者が SiriKit の導入に役立ついくつかの作業を行う必要があります。

共通共有コードの移動

最初に、開発者は、アプリと拡張機能の間で共有される一般的なコードの一部を 、共有プロジェクトポータブル クラス ライブラリ (PCL) または ネイティブ ライブラリのいずれかに移動できます。

拡張機能は、アプリが行うすべての操作を実行できる必要があります。 サンプルの MonkeyChat アプリでは、連絡先の検索、新しい連絡先の追加、メッセージの送信、メッセージ履歴の取得などが含まれます。

この共通コードを共有プロジェクト、PCL、またはネイティブ ライブラリに移動することで、そのコードを 1 つの共通の場所に簡単に維持でき、拡張機能と親アプリがユーザーに統一されたエクスペリエンスと機能を提供できるようになります。

サンプル アプリの MonkeyChat の場合、ネットワークやデータベースへのアクセスなどのデータ モデルと処理コードはネイティブ ライブラリに移動されます。

次の操作を行います。

  1. Visual Studio for Macを起動し、MonkeyChat アプリを開きます。

  2. Solution Pad でソリューション名を右クリックし、[新しいプロジェクト追加]> を選択します。

    新しいプロジェクトの追加

  3. [ iOS>ライブラリ>クラス ライブラリ ] を選択し、[ 次へ ] ボタンをクリックします。

    クラス ライブラリの選択

  4. [名前] に「」と入力MonkeyChatCommonし、[作成] ボタンをクリックします。

    [名前] に「MonkeyChatCommon」と入力します

  5. ソリューション エクスプローラーでメイン アプリの References フォルダーを右クリックし、[参照の編集]を選択します。MonkeyChatCommon プロジェクトを確認し、[OK] ボタンをクリックします

    MonkeyChatCommon プロジェクトを確認する

  6. ソリューション エクスプローラーで、共通の共有コードをメイン アプリからネイティブ ライブラリにドラッグします。

  7. MonkeyChat の場合は、dataModels フォルダーと Processors フォルダーをメイン アプリからネイティブ ライブラリにドラッグします。

    ソリューション エクスプローラー内の DataModels フォルダーとプロセッサ フォルダー

ネイティブ ライブラリに移動されたすべてのファイルを編集し、ライブラリの名前空間と一致するように名前空間を変更します。 たとえば、 を に変更 MonkeyChat します MonkeyChatCommon

using System;
namespace MonkeyChatCommon
{
    /// <summary>
    /// A message sent from one user to another within a conversation.
    /// </summary>
    public class MonkeyMessage
    {
        public MonkeyMessage ()
        {
        }
        ...
    }
}

次に、メイン アプリに戻り、移動されたクラスの 1 つをアプリが使用する任意の場所に、ネイティブ ライブラリの名前空間のステートメントを追加usingします。

using System;
using System.Collections.Generic;
using UIKit;
using Foundation;
using CoreGraphics;
using MonkeyChatCommon;

namespace MonkeyChat
{
    public partial class MasterViewController : UITableViewController
    {
        public DetailViewController DetailViewController { get; set; }

        DataSource dataSource;
        ...
    }
}

拡張機能用アプリの設計

通常、アプリは複数の意図にサインアップし、開発者はアプリが適切な数の意図拡張機能用に設計されていることを確認する必要があります。

アプリに複数の意図が必要な場合、開発者は、すべての意図処理を 1 つの意図拡張機能に配置するか、意図ごとに個別の意図拡張機能を作成することができます。

意図ごとに個別の意図拡張機能を作成する場合、開発者は各拡張機能で大量の定型コードを複製し、大量のプロセッサとメモリのオーバーヘッドを作成する可能性があります。

2 つのオプションを選択するには、いずれかの意図が自然に一緒に属しているかどうかを確認します。 たとえば、オーディオ呼び出しとビデオ呼び出しを行ったアプリでは、似たタスクを処理しており、コードの再利用が最も多い可能性があるため、これらの意図の両方を 1 つの意図拡張機能に含める必要がある場合があります。

既存のグループに収まらない意図または意図のグループについては、アプリのソリューションに新しい意図拡張機能を作成して含めます。

必須エンタイトルメントの設定

SiriKit 統合を含む Xamarin.iOS アプリには、正しいエンタイトルメントが設定されている必要があります。 開発者がこれらの必須エンタイトルメントを正しく設定していない場合、iOS 10 シミュレーターでは SiriKit がサポートされていないため、実際の iOS 10 (またはそれ以上) のハードウェアでアプリをインストールまたはテストすることはできません。

次の操作を行います。

  1. ソリューション エクスプローラー内のファイルをダブルクリックEntitlements.plistして、編集用に開きます。

  2. [ソース] タブに切り替えます。

  3. プロパティを追加しcom.apple.developer.siriType を にBooleanValue を にYes設定します。

    com.apple.developer.siri プロパティを追加する

  4. 変更をファイルに保存します。

  5. ソリューション エクスプローラー[プロジェクト ファイル] をダブルクリックして、編集用に開きます。

  6. [iOS バンドル署名] を選択し、[カスタム エンタイトルメント] フィールドでファイルが選択されていることを確認Entitlements.plistします。

    [カスタム エンタイトルメント] フィールドで Entitlements.plist ファイルを選択します

  7. [OK] ボタンをクリックして、変更を保存します。

完了すると、アプリの Entitlements.plist ファイルは次のようになります (外部エディターで開かれています)。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.developer.siri</key>
    <true/>
</dict>
</plist>

アプリの正しいプロビジョニング

Apple が SiriKit フレームワークの周りに配置した厳格なセキュリティのため、SiriKit を実装する Xamarin.iOS アプリには、正しいアプリ ID とエンタイトルメント (上記のセクションを参照) が 必要 であり、適切なプロビジョニング プロファイルで署名する必要があります。

Mac で次の操作を行います。

  1. Web ブラウザーで、 に移動し https://developer.apple.com 、アカウントにログインします。

  2. [証明書、識別子、およびプロファイル] クリックします。

  3. [ プロビジョニング プロファイル] を選択し、[ アプリ ID] を選択し、ボタンを + クリックします。

  4. 新しいプロファイルの名前を入力 します

  5. Apple の名前付けの推奨事項に従って 、バンドル ID を 入力します。

  6. [App Services] セクションまで下にスクロールし、[SiriKit] を選択し、[続行] ボタンをクリックします。

    SiriKit を選択する

  7. すべての設定を確認し、アプリ ID を 送信 します。

  8. [プロビジョニング プロファイル開発]> を選択し、ボタンを+クリックし、Apple ID を選択して、[続行] をクリックします。

  9. [ すべて選択] をクリックし、[ 続行] をクリックします。

  10. [ すべて選択 ] をもう一度クリックし、[ 続行] をクリックします。

  11. Apple の名前付け候補を使用して プロファイル名 を入力し、[ 続行] をクリックします。

  12. Xcode を起動します。

  13. [Xcode] メニューの [ 基本設定] を選択します。

  14. [ アカウント] を選択し、[ 詳細の表示 ]ボタンをクリックします。

    [アカウント] を選択する

  15. 左下隅 にある [すべてのプロファイルのダウンロード ] ボタンをクリックします。

    すべてのプロファイルをダウンロードする

  16. 上記で作成した プロビジョニング プロファイル が Xcode にインストールされていることを確認します。

  17. プロジェクトを開き、Visual Studio for Macで SiriKit サポートを に追加します。

  18. ソリューション エクスプローラー内のファイルをダブルクリックしますInfo.plist

  19. バンドル識別子が、上記の Apple の開発者ポータルで作成されたものと一致していることを確認します。

    バンドル識別子

  20. ソリューション エクスプローラーで、[プロジェクト] を選択します

  21. プロジェクトを右クリックし、[ オプション] を選択します。

  22. [ iOS バンドル署名] を選択し、上記で作成した 署名 IDプロビジョニング プロファイルを 選択します。

    署名 ID とプロビジョニング プロファイルを選択する

  23. [OK] ボタンをクリックして、変更を保存します。

重要

SiriKit のテストは、iOS 10 シミュレーターではなく、実際の iOS 10 ハードウェア デバイスでのみ機能します。 SiriKit 対応 Xamarin.iOS アプリを実際のハードウェアにインストールする際に問題が発生した場合は、Apple の開発者ポータルとVisual Studio for Macの両方で、必要なエンタイトルメント、アプリ ID、署名識別子、プロビジョニング プロファイルが正しく構成されていることを確認します。

Siri 承認の要求

アプリがユーザー固有のボキャブラリまたは意図拡張機能を Siri に接続する前に、Siri にアクセスするための承認をユーザーに要求する必要があります。

アプリの Info.plist ファイルを編集し、[ ソース ] ビューに切り替え、アプリで Siri を使用する方法と送信されるデータの種類を説明する文字列値を含むキーを追加 NSSiriUsageDescription します。 たとえば、MonkeyChat アプリに "MonkeyChat 連絡先が Siri に送信されます" と表示される場合があります。

Info.plist エディターの NSSiriUsageDescription

アプリの RequestSiriAuthorization 初回起動時に INPreferences クラスの メソッドを呼び出します。 クラスを AppDelegate.cs 編集し、 メソッドを FinishedLaunching 次のようにします。

using Intents;
...

public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{

    // Request access to Siri
    INPreferences.RequestSiriAuthorization ((INSiriAuthorizationStatus status) => {
        // Respond to returned status
        switch (status) {
        case INSiriAuthorizationStatus.Authorized:
            break;
        case INSiriAuthorizationStatus.Denied:
            break;
        case INSiriAuthorizationStatus.NotDetermined:
            break;
        case INSiriAuthorizationStatus.Restricted:
            break;
        }
    });

    return true;
}

このメソッドが初めて呼び出されると、アプリが Siri にアクセスすることをユーザーに求める警告が表示されます。 開発者が上記に NSSiriUsageDescription 追加したメッセージは、このアラートに表示されます。 ユーザーが最初にアクセスを拒否した場合は、 設定 アプリを使用してアプリへのアクセスを許可できます。

アプリは、クラスの メソッドを呼び出すことによって、いつでも Siri にアクセスするアプリの機能をSiriAuthorizationStatusINPreferencesチェックできます。

ローカリゼーションと Siri

iOS デバイスでは、ユーザーは、システムの既定値とは異なる Siri の言語を選択できます。 ローカライズされたデータを操作する場合、アプリは クラスの INPreferences メソッドをSiriLanguageCode使用して Siri から言語コードを取得する必要があります。 次に例を示します。

var language = INPreferences.SiriLanguageCode();

// Take action based on language
if (language == "en-US") {
    // Do something...
}

ユーザー固有のボキャブラリの追加

ユーザー固有のボキャブラリは、アプリの個々のユーザーに固有の単語またはフレーズを提供します。 これらは、実行時にメイン アプリから (App Extensions ではなく) 順序付けされた一連の用語として提供され、ユーザーにとって最も重要な使用優先順位で並べ替えられます。最も重要な用語は一覧の先頭に表示されます。

ユーザー固有のボキャブラリは、次のいずれかのカテゴリに属している必要があります。

  • 連絡先名 (連絡先フレームワークによって管理されない)。
  • 写真タグ。
  • フォト アルバム名。
  • ワークアウト名。

カスタム ボキャブラリとして登録する用語を選択する場合は、アプリに慣れていないユーザーによって誤解される可能性がある用語のみを選択します。 "マイ ワークアウト" や "マイ アルバム" などの一般的な用語を登録しないでください。 たとえば、MonkeyChat アプリは、ユーザーのアドレス帳の各連絡先に関連付けられているニックネームを登録します。

アプリは、 クラスの メソッドINVocabularySetVocabularyStrings呼び出し、メイン アプリからコレクションをNSOrderedSet渡すことによって、ユーザー固有のボキャブラリを提供します。 アプリでは、新しい用語を追加する前に既存の RemoveAllVocabularyStrings 用語を削除するために、常に最初に メソッドを呼び出す必要があります。 次に例を示します。

using System;
using System.Linq;
using System.Collections.Generic;
using Foundation;
using Intents;

namespace MonkeyChatCommon
{
    public class MonkeyAddressBook : NSObject
    {
        #region Computed Properties
        public List<MonkeyContact> Contacts { get; set; } = new List<MonkeyContact> ();
        #endregion

        #region Constructors
        public MonkeyAddressBook ()
        {
        }
        #endregion

        #region Public Methods
        public NSOrderedSet<NSString> ContactNicknames ()
        {
            var nicknames = new NSMutableOrderedSet<NSString> ();

            // Sort contacts by the last time used
            var query = Contacts.OrderBy (contact => contact.LastCalledOn);

            // Assemble ordered list of nicknames by most used to least
            foreach (MonkeyContact contact in query) {
                nicknames.Add (new NSString (contact.ScreenName));
            }

            // Return names
            return new NSOrderedSet<NSString> (nicknames.AsSet ());
        }

        // This method MUST only be called on a background thread!
        public void UpdateUserSpecificVocabulary ()
        {
            // Clear any existing vocabulary
            INVocabulary.SharedVocabulary.RemoveAllVocabularyStrings ();

            // Register new vocabulary
            INVocabulary.SharedVocabulary.SetVocabularyStrings (ContactNicknames (), INVocabularyStringType.ContactName);
        }
        #endregion
    }
}

このコードを配置すると、次のように呼び出される場合があります。

using System;
using System.Threading;
using UIKit;
using MonkeyChatCommon;
using Intents;

namespace MonkeyChat
{
    public partial class ViewController : UIViewController
    {
        #region AppDelegate Access
        public AppDelegate ThisApp {
            get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Constructors
        protected ViewController (IntPtr handle) : base (handle)
        {
            // Note: this .ctor should not contain any initialization logic.
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Do we have access to Siri?
            if (INPreferences.SiriAuthorizationStatus == INSiriAuthorizationStatus.Authorized) {
                // Yes, update Siri's vocabulary
                new Thread (() => {
                    Thread.CurrentThread.IsBackground = true;
                    ThisApp.AddressBook.UpdateUserSpecificVocabulary ();
                }).Start ();
            }
        }

        public override void DidReceiveMemoryWarning ()
        {
            base.DidReceiveMemoryWarning ();
            // Release any cached data, images, etc that aren't in use.
        }
        #endregion
    }
}

重要

Siri はカスタムボキャブラリをヒントとして扱い、できるだけ多くの用語を組み込みます。 ただし、カスタム ボキャブラリの領域は限られているため、混乱を招く可能性のある用語 のみを 登録することが重要であるため、登録された用語の合計数を最小限に抑える必要があります。

詳細については、 ユーザー固有のボキャブラリ リファレンス と Apple の カスタム ボキャブラリ リファレンスの指定に関するページを参照してください

アプリ固有のボキャブラリの追加

アプリ固有のボキャブラリは、車両の種類やワークアウト名など、アプリのすべてのユーザーに認識される特定の単語とフレーズを定義します。 これらはアプリケーションの一部であるため、メイン アプリ バンドルの一部としてファイルでAppIntentVocabulary.plist定義されます。 さらに、これらの単語と語句をローカライズする必要があります。

アプリ固有のボキャブラリ用語は、次のいずれかのカテゴリに属している必要があります。

  • 乗車オプション。
  • ワークアウト名。

アプリ固有のボキャブラリ ファイルには、次の 2 つのルート レベル キーが含まれています。

  • ParameterVocabularies必須 - 適用するアプリのカスタム用語と意図パラメーターを定義します。
  • IntentPhrases省略可能 - で定義されているカスタム用語を使用したフレーズの例が ParameterVocabularies含まれます。

ParameterVocabularies の各エントリでは、ID 文字列、用語、および用語が適用される意図を指定する必要があります。 さらに、1 つの用語が複数の意図に適用される場合があります。

許容される値と必要なファイル構造の完全な一覧については、「Apple の アプリ ボキャブラリ ファイル形式リファレンス」を参照してください。

アプリ プロジェクトにファイルを AppIntentVocabulary.plist 追加するには、次の操作を行います。

  1. ソリューション エクスプローラーで [プロジェクト名] を右クリックし、[新しいファイル追加]>を選択します。>iOS:

    プロパティ リストを追加する

  2. ソリューション エクスプローラー内のファイルをダブルクリックAppIntentVocabulary.plistして、編集用に開きます。

  3. + クリックしてキーを追加し、[ 名前] を に ParameterVocabulariesType を に Array設定します。

    Name を ParameterVocabularies に設定し、Type を Array に設定します。

  4. ボタンを+展開ParameterVocabulariesしてクリックし、[種類] を にDictionary設定します。

    [種類] を [辞書] に設定する

  5. + クリックして新しいキーを追加し、[ 名前] を に ParameterNamesType を に Array設定します。

    [名前] を [ParameterNames] に設定し、[型] を [配列] に設定します。

  6. + クリックして、 Type が の String 新しいキーと、使用可能なパラメーター名の 1 つとして値を追加します。 INStartWorkoutIntent.workoutName の例を次に示します。

    INStartWorkoutIntent.workoutName キー

  7. ArrayParameterVocabularyParameterVocabulariesキーにキーを追加します。

    ParameterVocabulary キーを、配列の型を使用して ParameterVocabularies キーに追加します

  8. Dictionaryが の新しいキーを追加します。

    Visual Studio for Macの [辞書の種類] を使用して新しいキーを追加します。

  9. TypeVocabularyItemIdentifierStringキーを追加し、用語の一意の ID を指定します。

    文字列型を使用して VocabularyItemIdentifier キーを追加し、一意の ID を指定します

  10. Arrayが のVocabularyItemSynonymsキーを追加します。

    Array の型を使用して VocabularyItemSynonyms キーを追加する

  11. Dictionaryが の新しいキーを追加します。

    Visual Studio for Macの [辞書の種類] を使用して、別の新しいキーを追加します。

  12. String が のVocabularyItemPhraseキーと、アプリで定義されている用語を追加します。

    文字列型とアプリが定義している用語を使用して、VocabularyItemPhrase キーを追加します

  13. VocabularyItemPronunciation種類Stringと用語の発音を使用してキーを追加します。

    文字列の種類と用語の発音を使用して、VocabularyItemPronunciation キーを追加します

  14. Arrayが のVocabularyItemExamplesキーを追加します。

    Array の型を使用して VocabularyItemExamples キーを追加する

  15. 用語の使用例を使用して、いくつかの String キーを追加します。

    Visual Studio for Macの用語の使用例を含む文字列キーをいくつか追加します。

  16. アプリで定義する必要があるその他のカスタム用語については、上記の手順を繰り返します。

  17. キーを ParameterVocabularies 折りたたみます。

  18. Arrayが のIntentPhrasesキーを追加します。

    配列の型を使用して IntentPhrases キーを追加する

  19. Dictionaryが の新しいキーを追加します。

    Visual Studio for Macの [辞書の種類] を使用して、新しいキーを追加します。

  20. 次の IntentName 例の TypeString Intent を使用してキーを追加します。

    例の String と Intent の型を使用して IntentName キーを追加します

  21. Arrayが のIntentExamplesキーを追加します。

    配列の型を使用して IntentExamples キーを追加する

  22. 用語の使用例を使用して、いくつかの String キーを追加します。

    Visual Studio for Macの用語の使用例を使用して、いくつかの文字列キーを追加します。

  23. アプリで使用例を提供する必要がある意図について、上記の手順を繰り返します。

重要

AppIntentVocabulary.plist 開発中にテスト デバイスで Siri に登録され、Siri がカスタム ボキャブラリを組み込むのに時間がかかる場合があります。 その結果、テスト担当者は、更新されたアプリ固有のボキャブラリをテストする前に数分待つ必要があります。

詳細については、 アプリ固有のボキャブラリ リファレンス と Apple の カスタム ボキャブラリ リファレンスの指定に関するページを参照してください

意図拡張機能の追加

アプリが SiriKit を採用する準備ができたので、開発者は、Siri 統合に必要な意図を処理するために、ソリューションに 1 つ (または複数) の意図拡張機能を追加する必要があります。

必要な意図拡張機能ごとに、次の操作を行います。

  • 意図拡張機能プロジェクトを Xamarin.iOS アプリ ソリューションに追加します。
  • Intents Extension Info.plist ファイルを構成します。
  • Intents Extension メイン クラスを変更します。

詳細については、 意図拡張機能リファレンス と Apple の意図拡張機能の 作成に関するリファレンスを参照してください

拡張機能の作成

ソリューションに意図拡張機能を追加するには、次の操作を行います。

  1. Solution Pad[ソリューション名] を右クリックし、[新しいプロジェクトの追加]> を選択します。

  2. ダイアログ ボックスから [ iOS>拡張機能>の意図拡張機能 ] を選択し、[ 次へ ] ボタンをクリックします。

    [意図の拡張機能] を選択する

  3. 次に、インテント拡張機能の 名前 を入力し、[ 次へ ] ボタンをクリックします。

    意図拡張の名前を入力します。

  4. 最後に、[ 作成 ] ボタンをクリックして、意図拡張機能をアプリ ソリューションに追加します。

    意図拡張機能をアプリ ソリューションに追加します。

  5. ソリューション エクスプローラーで、新しく作成された意図拡張機能の References フォルダーを右クリックします。 共通の共有コード ライブラリ プロジェクト (上記で作成したアプリ) の名前を確認し、[OK] ボタンをクリック します

    共通の共有コード ライブラリ プロジェクトの名前を選択します。

アプリに必要な意図拡張機能の数 (上記の [ 拡張機能用アプリの設計 ] セクションに基づく) に対して、これらの手順を繰り返します。

Info.plist の構成

アプリのソリューションに追加された意図拡張機能ごとに、アプリを操作するようにファイルで Info.plist を構成する必要があります。

一般的なアプリ拡張機能と同様に、アプリには と NSExtensionAttributesの既存のNSExtensionキーが含まれます。 インテント拡張機能には、次の 2 つの新しい属性を構成する必要があります。

構成する必要がある 2 つの新しい属性

  • IntentsSupported - 必須であり、アプリがインテント拡張機能からサポートする意図クラス名の配列で構成されます。
  • IntentsRestrictedWhileLocked - 拡張機能のロック画面の動作を指定するアプリの省略可能なキーです。 これは、アプリが意図拡張機能から使用するためにユーザーのログインを要求する意図クラス名の配列で構成されます。

インテント拡張機能Info.plistのファイルを構成するには、ソリューション エクスプローラーでダブルクリックして編集用に開きます。 次に、ソース ビューに切り替え、エディターで キーと NSExtensionAttributes キーを展開NSExtensionします。

キーを IntentsSupported 展開し、この拡張機能でサポートされるインテント クラスの名前を追加します。 例の MonkeyChat アプリでは、 が INSendMessageIntentサポートされています。

アプリで必要に応じて、特定の意図を使用するためにユーザーをデバイスにログオンさせる必要がある場合は、キーを IntentRestrictedWhileLocked 展開し、アクセスが制限されている意図のクラス名を追加します。 例の MonkeyChat アプリでは、チャット メッセージを送信するためにユーザーがログインしている必要があるため、 を追加 INSendMessageIntentしました。

使用可能な意図ドメインの完全な一覧については、「Apple の インテント ドメイン リファレンス」を参照してください。

メイン クラスの構成

次に、開発者は、Siri へのインテント拡張機能のメインエントリ ポイントとして機能するメイン クラスを構成する必要があります。 デリゲートに準拠IINIntentHandlerする サブクラスINExtensionである必要があります。 次に例を示します。

using System;
using System.Collections.Generic;

using Foundation;
using Intents;

namespace MonkeyChatIntents
{
    [Register ("IntentHandler")]
    public class IntentHandler : INExtension, IINSendMessageIntentHandling, IINSearchForMessagesIntentHandling, IINSetMessageAttributeIntentHandling
    {
        #region Constructors
        protected IntentHandler (IntPtr handle) : base (handle)
        {
            // Note: this .ctor should not contain any initialization logic.
        }
        #endregion

        #region Override Methods
        public override NSObject GetHandler (INIntent intent)
        {
            // This is the default implementation.  If you want different objects to handle different intents,
            // you can override this and return the handler you want for that particular intent.

            return this;
        }
        #endregion
        ...
    }
}

アプリが Intent Extension メイン クラス ( メソッド) に実装する必要がある単一のメソッドが GetHandler 1 つあります。 このメソッドは SiriKit によって Intent に渡され、アプリは、指定された意図の種類に一致する インテント ハンドラー を返す必要があります。

例の MonkeyChat アプリは 1 つの意図のみを処理するため、 メソッドでそれ自体を GetHandler 返しています。 拡張機能が複数の意図を処理した場合、開発者は意図の種類ごとにクラスを追加し、 メソッドに渡された に Intent 基づいてインスタンスをここに返します。

解決ステージの処理

解決ステージは、意図拡張機能が Siri から渡され、ユーザーの会話を介して設定されたパラメーターを明確にして検証する場所です。

Siri から送信されるパラメーターごとに、 メソッドがあります Resolve 。 アプリは、ユーザーから正しい答えを得るために Siri のヘルプを必要とする可能性があるすべてのパラメーターに対して、このメソッドを実装する必要があります。

例の MonkeyChat アプリの場合、意図拡張機能では、メッセージの送信先として 1 人以上の受信者が必要になります。 リスト内の受信者ごとに、拡張機能は次の結果を得ることができる連絡先検索を実行する必要があります。

  • 一致する連絡先が 1 つだけ見つかりました。
  • 2 つ以上の一致する連絡先が見つかります。
  • 一致する連絡先が見つかりません。

さらに、MonkeyChat には、メッセージの本文のコンテンツが必要です。 ユーザーがこれを指定していない場合、Siri はユーザーにコンテンツの入力を求める必要があります。

意図拡張機能では、これらの各ケースを適切に処理する必要があります。

[Export ("resolveRecipientsForSearchForMessages:withCompletion:")]
public void ResolveRecipients (INSendMessageIntent intent, Action<INPersonResolutionResult []> completion)
{
    var recipients = intent.Recipients;
    // If no recipients were provided we'll need to prompt for a value.
    if (recipients.Length == 0) {
        completion (new INPersonResolutionResult [] { (INPersonResolutionResult)INPersonResolutionResult.NeedsValue });
        return;
    }

    var resolutionResults = new List<INPersonResolutionResult> ();

    foreach (var recipient in recipients) {
        var matchingContacts = new INPerson [] { recipient }; // Implement your contact matching logic here to create an array of matching contacts
        if (matchingContacts.Length > 1) {
            // We need Siri's help to ask user to pick one from the matches.
            resolutionResults.Add (INPersonResolutionResult.GetDisambiguation (matchingContacts));
        } else if (matchingContacts.Length == 1) {
            // We have exactly one matching contact
            resolutionResults.Add (INPersonResolutionResult.GetSuccess (recipient));
        } else {
            // We have no contacts matching the description provided
            resolutionResults.Add ((INPersonResolutionResult)INPersonResolutionResult.Unsupported);
        }
    }

    completion (resolutionResults.ToArray ());
}

[Export ("resolveContentForSendMessage:withCompletion:")]
public void ResolveContent (INSendMessageIntent intent, Action<INStringResolutionResult> completion)
{
    var text = intent.Content;
    if (!string.IsNullOrEmpty (text))
        completion (INStringResolutionResult.GetSuccess (text));
    else
        completion ((INStringResolutionResult)INStringResolutionResult.NeedsValue);
}

詳細については、 Resolve Stage Reference と Apple の 意図の解決と処理に関するリファレンスを参照してください

確認ステージの処理

確認ステージは、意図拡張機能がユーザーの要求を満たすためにすべての情報を持っていることを確認する場所です。 アプリは、Siri に何が起こるかをサポートするすべての詳細を確認して、これが意図したアクションであることをユーザーに確認できるように、確認を送信したいと考えています。

[Export ("confirmSendMessage:completion:")]
public void ConfirmSendMessage (INSendMessageIntent intent, Action<INSendMessageIntentResponse> completion)
{
    // Verify user is authenticated and the app is ready to send a message.
    ...

    var userActivity = new NSUserActivity (nameof (INSendMessageIntent));
    var response = new INSendMessageIntentResponse (INSendMessageIntentResponseCode.Ready, userActivity);
    completion (response);
}

詳細については、 ステージの確認に関するリファレンスを参照してください

意図の処理

これは、ユーザーの要求を満たし、結果を Siri に渡してユーザーに通知できるようにするために、意図拡張機能が実際にタスクを実行するポイントです。

public void HandleSendMessage (INSendMessageIntent intent, Action<INSendMessageIntentResponse> completion)
{
    // Implement the application logic to send a message here.
    ...

    var userActivity = new NSUserActivity (nameof (INSendMessageIntent));
    var response = new INSendMessageIntentResponse (INSendMessageIntentResponseCode.Success, userActivity);
    completion (response);
}

public void HandleSearchForMessages (INSearchForMessagesIntent intent, Action<INSearchForMessagesIntentResponse> completion)
{
    // Implement the application logic to find a message that matches the information in the intent.
    ...

    var userActivity = new NSUserActivity (nameof (INSearchForMessagesIntent));
    var response = new INSearchForMessagesIntentResponse (INSearchForMessagesIntentResponseCode.Success, userActivity);

    // Initialize with found message's attributes
    var sender = new INPerson (new INPersonHandle ("sarah@example.com", INPersonHandleType.EmailAddress), null, "Sarah", null, null, null);
    var recipient = new INPerson (new INPersonHandle ("+1-415-555-5555", INPersonHandleType.PhoneNumber), null, "John", null, null, null);
    var message = new INMessage ("identifier", "I am so excited about SiriKit!", NSDate.Now, sender, new INPerson [] { recipient });
    response.Messages = new INMessage [] { message };
    completion (response);
}

public void HandleSetMessageAttribute (INSetMessageAttributeIntent intent, Action<INSetMessageAttributeIntentResponse> completion)
{
    // Implement the application logic to set the message attribute here.
    ...

    var userActivity = new NSUserActivity (nameof (INSetMessageAttributeIntent));
    var response = new INSetMessageAttributeIntentResponse (INSetMessageAttributeIntentResponseCode.Success, userActivity);
    completion (response);
}

詳細については、 ハンドル ステージ リファレンスに関するページを参照してください。

意図 UI 拡張機能の追加

オプションの Intents UI 拡張機能は、アプリの UI とブランドを Siri エクスペリエンスに取り込み、ユーザーにアプリへの接続を感じさせる機会を提供します。 この拡張機能を使用すると、アプリはブランドだけでなく、ビジュアルやその他の情報をトランスクリプトに取り込むことができます。

意図 UI 拡張機能の出力例

意図拡張機能と同様に、開発者は Intents UI 拡張機能に対して次の手順を実行します。

  • 意図 UI 拡張機能プロジェクトを Xamarin.iOS アプリ ソリューションに追加します。
  • Intents UI Extension Info.plist ファイルを構成します。
  • Intents UI Extension メイン クラスを変更します。

詳細については、 意図 UI 拡張機能リファレンス と Apple の カスタム インターフェイスリファレンスの提供に関するページを参照してください

拡張機能の作成

ソリューションに Intents UI 拡張機能を追加するには、次の操作を行います。

  1. Solution Pad[ソリューション名] を右クリックし、[新しいプロジェクトの追加]> を選択します。

  2. ダイアログ ボックスで [ iOS>拡張機能>インテント UI 拡張機能 ] を選択し、[ 次へ ] ボタンをクリックします。

    [意図 UI 拡張機能] を選択します

  3. 次に、インテント拡張機能の 名前 を入力し、[ 次へ ] ボタンをクリックします。

    Visual Studio for Macに意図拡張の名前を入力します。

  4. 最後に、[ 作成 ] ボタンをクリックして、意図拡張機能をアプリ ソリューションに追加します。

    Visual Studio for Macのアプリ ソリューションにインテント拡張機能を追加します。

  5. ソリューション エクスプローラーで、新しく作成された意図拡張機能の References フォルダーを右クリックします。 共通の共有コード ライブラリ プロジェクト (上記で作成したアプリ) の名前を確認し、[OK] ボタンをクリック します

    Visual Studio for Macで共通の共有コード ライブラリ プロジェクトの名前を選択します。

Info.plist の構成

意図 UI 拡張機能の Info.plist ファイルを構成して、アプリを操作します。

一般的なアプリ拡張機能と同様に、アプリには と NSExtensionAttributesの既存のNSExtensionキーが含まれます。 意図拡張機能の場合、構成する必要がある新しい属性が 1 つあります。

構成する必要がある 1 つの新しい属性

IntentsSupported は必須であり、アプリがインテント拡張機能からサポートする意図クラス名の配列で構成されます。

インテント UI 拡張機能のInfo.plistファイルを構成するには、ソリューション エクスプローラーでダブルクリックして編集用に開きます。 次に、ソース ビューに切り替え、エディターで キーと NSExtensionAttributes キーを展開NSExtensionします。

エディターの NSExtension キーと NSExtensionAttributes キー。

キーを IntentsSupported 展開し、この拡張機能でサポートされるインテント クラスの名前を追加します。 例の MonkeyChat アプリでは、 が INSendMessageIntentサポートされています。

使用可能な意図ドメインの完全な一覧については、「Apple の 意図ドメイン リファレンス」を参照してください。

メイン クラスの構成

インテント UI 拡張機能のメイン エントリ ポイントとして機能する メイン クラスを Siri に構成します。 インターフェイスに準拠IINUIHostedViewControllerする のUIViewControllerサブクラスである必要があります。 次に例を示します。

using System;
using Foundation;
using CoreGraphics;
using Intents;
using IntentsUI;
using UIKit;

namespace MonkeyChatIntentsUI
{
    public partial class IntentViewController : UIViewController, IINUIHostedViewControlling
    {
        #region Constructors
        protected IntentViewController (IntPtr handle) : base (handle)
        {
            // Note: this .ctor should not contain any initialization logic.
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Do any required interface initialization here.
        }

        public override void DidReceiveMemoryWarning ()
        {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning ();

            // Release any cached data, images, etc that aren't in use.
        }
        #endregion

        #region Public Methods
        [Export ("configureWithInteraction:context:completion:")]
        public void Configure (INInteraction interaction, INUIHostedViewContext context, Action<CGSize> completion)
        {
            // Do configuration here, including preparing views and calculating a desired size for presentation.

            if (completion != null)
                completion (DesiredSize ());
        }

        [Export ("desiredSize:")]
        public CGSize DesiredSize ()
        {
            return ExtensionContext.GetHostedViewMaximumAllowedSize ();
        }
        #endregion
    }
}

Siri は、インテント UI 拡張機能内の Configure インスタンスの メソッドにUIViewControllerクラス インスタンスを渡INInteractionします。

オブジェクトは INInteraction 、次の 3 つの重要な情報を拡張機能に提供します。

  1. 処理中の Intent オブジェクト。
  2. 意図拡張の Confirm メソッドと Handle メソッドからの Intent Response オブジェクト。
  3. アプリと Siri の間の相互作用の状態を定義する相互作用状態。

インスタンスは UIViewController Siri との対話の原則クラスであり、 から UIViewController継承されるため、UIKit のすべての機能にアクセスできます。

Siri が の メソッドをConfigureUIViewController呼び出すと、ビュー コントローラーが Siri Snippit または Maps カードでホストされることを示すビュー コンテキストで渡されます。

Siri は、アプリの構成が完了したら、アプリがビューの目的のサイズを返す必要がある完了ハンドラーも渡します。

iOS Designerで UI を設計する

iOS Designerで意図 UI 拡張機能のユーザー インターフェイスをレイアウトします。 ソリューション エクスプローラー内の拡張機能のMainInterface.storyboardファイルをダブルクリックして、編集用に開きます。 必要なすべての UI 要素をドラッグしてユーザー インターフェイスを構築し、変更を保存します。

重要

や などのUIButtonsUITextFields対話型要素をインテント UI 拡張機能UIViewControllerに追加することはできますが、これらは非対話型の意図 UI として厳密に禁止されており、ユーザーはそれらを操作できません。

ユーザー インターフェイスをWire-Upする

iOS Designerで作成された Intents UI 拡張機能のユーザー インターフェイスを使用して、サブクラスをUIViewController編集し、メソッドをConfigure次のようにオーバーライドします。

[Export ("configureWithInteraction:context:completion:")]
public void Configure (INInteraction interaction, INUIHostedViewContext context, Action<CGSize> completion)
{
    // Do configuration here, including preparing views and calculating a desired size for presentation.
    ...

    // Return desired size
    if (completion != null)
        completion (DesiredSize ());
}

[Export ("desiredSize:")]
public CGSize DesiredSize ()
{
    return ExtensionContext.GetHostedViewMaximumAllowedSize ();
}

既定の Siri UI のオーバーライド

意図 UI 拡張機能は、アプリアイコンや UI の上部にある名前などの他の Siri コンテンツと共に常に表示されます。また、意図に基づいて、ボタン ([送信] や [キャンセル] など) が下部に表示される場合があります。

アプリが既定でユーザーに表示している情報 (メッセージングやマップなど) をアプリが置き換えることができるインスタンスがいくつかあります。この場合、アプリは既定のエクスペリエンスをアプリに合わせたエクスペリエンスに置き換えることができます。

意図 UI 拡張機能で既定の Siri UI の要素をオーバーライドする必要がある場合、サブクラスは インターフェイスをIINUIHostedViewSiriProviding実装し、UIViewController特定のインターフェイス要素を表示することをオプトインする必要があります。

次のコードをサブクラスに追加して UIViewController 、意図 UI 拡張機能にメッセージの内容が既に表示されていることを Siri に伝えます。

public bool DisplaysMessage {
    get {return true;}
}

考慮事項

Apple は、意図 UI 拡張機能を設計および実装する際に、開発者が次の考慮事項を考慮に入れると提案しています。

  • メモリ使用量を意識 する - インテント UI 拡張機能は一時的なもので、短時間だけ表示されるため、システムでは、完全なアプリで使用されるよりも厳しいメモリ制約が課されます。
  • 最小表示サイズと最大表示サイズを考慮 する - すべての iOS デバイスの種類、サイズ、向きで意図 UI 拡張機能が適切に表示されていることを確認します。 さらに、アプリが Siri に送り返す目的のサイズを許可できない場合があります。
  • フレキシブルおよびアダプティブ レイアウト パターンを使用する - ここでも、すべてのデバイスで UI が適切に表示されるようにします。

まとめ

この記事では、SiriKit について説明し、Xamarin.iOS アプリに追加して、Siri と iOS デバイス上の Maps アプリを使用してユーザーがアクセスできるサービスを提供する方法について説明しました。