Xamarin.iOS の PassKit

iOS ウォレット アプリを使用すると、ユーザーはデバイスにデジタル パスを保存できます。 これらのパスは商品の販売元が生成し、メール、URL、または販売元の iOS アプリ内から顧客に送信されます。 パスは、映画のチケットからポイント カード、搭乗券まで、さまざまなものに使われます。 PassKit フレームワークを使用すると、開発者はプログラムでパスを操作できます。

このドキュメントでは、ウォレットと、Xamarin.iOS で PassKit API を使用する方法について説明します。

The Wallet stores and organizes all the passes on a phone

要件

このドキュメントで説明する PassKit 機能には、iOS 6 と Xcode 4.5、Xamarin.iOS 6.0 が必要です。

はじめに

PassKit が解決する主な問題は、バーコードの配布と管理です。 以下は、バーコードが現在使われている具体的な例です。

  • オンラインでの映画チケット購入 - 顧客には通常、チケットを表すバーコードがメールで送信されます。 このバーコードを印刷して映画館に持参し、入口でスキャンすると入場できます。
  • ポイント カード - 顧客は、商品を購入するときに、財布に入っている複数のポイント カードからその店舗のカードを出して提示し、スキャンしてもらいます。
  • クーポン - クーポンは、印刷可能な Web ページとしてメールで送られたり、郵便物で提供されたり、新聞や雑誌上のバーコードとして配布されます。 顧客は、これらを店舗に持ち込み、スキャンしてもらうことで、商品、サービス、割引を受け取ります。
  • 搭乗券 - 映画のチケット購入とほぼ同じです。

PassKit には、これらの場面に対応する代替の方法があります。

  • 映画チケット - 購入後、顧客は (メールまたは Web サイトのリンクを介して) イベント チケット パスを追加します。 映画の上映時間が近づくと、パスのリマインダーがロック画面に自動的に表示されるので、映画館に到着したらパスを簡単に開き、ウォレットに表示してスキャンに備えることができます。
  • ポイント カード - 物理的なカードを提供する (またはそれに加えて何かを提供する) のではなく、店舗は (メールまたは Web サイトへのログイン後に) ストア カード パスを発行できます。 店舗側は、プッシュ通知を使用して、パスのアカウントの残高を更新するなどの追加機能を提供できます。また、位置情報サービスを使用して、顧客が店舗の近くにいるときに、パスがロック画面に自動的に表示されるようにすることもできます。
  • クーポン - クーポンのパスは、追跡機能を持たせて簡単に生成することができ、メールや Web サイトのリンクを介して配布できます。 ユーザーが特定の場所に近づいた場合や、特定の日付が来たとき (有効期限が近づいている場合など) に、ダウンロードしたクーポンをロック画面に自動的に表示することもできます。 クーポンはユーザーの携帯電話に保存されるため、いつも手元にあり、なくす心配がありません。 パスには App Store のリンクを組み込むことができるため、クーポンの提供がコンパニオン アプリのダウンロードを促し、顧客とのつながりが高まる可能性もあります。
  • 搭乗券 - オンライン チェックイン プロセスの後、顧客はメールまたはリンクを介して搭乗券を受け取ります。 航空会社が提供するコンパニオン アプリにチェックイン プロセスを組み込むことができるほか、顧客が自分で座席指定や食事の選択などの追加機能を実行することもできます。 航空会社は、フライトの遅延やキャンセルが発生した場合に、プッシュ通知を使用してパスを更新できます。 搭乗時間が近づくと、リマインダーとしてパスがロック画面に表示されるため、すばやくパスにアクセスできます。

PassKit が主に提供するのは、iOS デバイスにバーコードを保存して表示するためのシンプルで便利な方法です。 時間や場所に合わせてロック画面に通知を表示し、プッシュ通知やコンパニオン アプリケーションを統合することで、洗練されたショッピング、チケット手配、課金サービスの基盤を実現できます。

PassKit エコシステム

PassKit は CocoaTouch 内の単なる API ではなく、バーコードやその他のデータの安全な共有と管理を容易にする、アプリ、データ、サービスの大規模なエコシステムの一部です。 この全体図は、パスの作成と使用に関与するさまざまなエンティティを示しています。

This high level diagram shows the entities involved in creating and using passes

エコシステムの各要素には、明確に定義された役割があります。

  • ウォレット - パスを保存、表示する Apple の組み込みの iOS アプリ。 これは、パスが現実世界で使用するためにレンダリングされる唯一の場所です (つまり、バーコードが、パス内のすべてのローカライズされたデータと共に表示されます)。
  • コンパニオン アプリ - パスの発行者が作成した、パスの機能を拡張 (ストア カードへの価値の追加、搭乗券に記載されている座席の変更、その他のビジネス固有の機能の追加など) するための iOS 6 アプリ。 コンパニオン アプリがなくても、パスは便利に利用できます。
  • サーバー - パスを生成して配布用に署名するためのセキュリティ保護されたサーバー。 コンパニオン アプリは、サーバーに接続して新しいパスを生成したり、既存のパスへの更新を要求する場合があります。 必要に応じて、パスを更新するためにウォレットが呼び出す Web サービス API を実装できます。
  • APNS サーバー - サーバーには、APNS を使用して、特定のデバイス上のパスに対する更新をウォレットに通知する機能があります。 ウォレットに通知をプッシュすると、変更の詳細を確認するためにサーバーへの問い合わせが行われます。 この機能のためにコンパニオン アプリが APNS を実装する必要はありません (ただし、PKPassLibraryDidChangeNotification をリッスンすることはできます)。
  • コンジット アプリ - パスをコンパニオン アプリのようには直接操作しないが、パスを認識してウォレットに追加できるようにすることで、そのユーティリティを強化するアプリケーション。 メール クライアント、ソーシャル ネットワーク ブラウザー、その他のデータ集計アプリはすべて、添付ファイルまたはパスへのリンクに遭遇する可能性があります。

エコシステム全体は複雑に見えますが、一部のコンポーネントは省略可能であり、より単純な PassKit 実装が可能です。

パスとは

パスは、チケット、クーポン、またはカードを表すデータのコレクションです。 これは、個人による 1 回の使用を意図している場合 (便名や座席指定などの詳細が含まれる場合)、または複数のユーザーで共有して何度も使用するトークンの場合 (割引クーポンなど) があります。 詳しい説明は、Apple のパス ファイルに関するドキュメントを参照してください。

現在サポートされているのは 5 種類で、ウォレット アプリでは、パスのレイアウトと上部の形で見分けることができます。

  • イベント チケット - 小さい半円の切切り欠きがあります。
  • 搭乗券 - 左右に V 字型の切り込みがあり、輸送手段を示すアイコン (バス、電車、飛行機など) を指定できます。
  • ストア カード - クレジットやデビット カードのように上部の角が丸くなっています。
  • クーポン - 上部にミシン目があります。
  • 一般 - ストア カードと同じく、上部の角が丸くなっています。

このスクリーンショットは、5 つのパスの種類 (クーポン、一般、ストア カード、搭乗券、イベント チケット) を示しています。

The five pass types are shown in this screenshot

ファイル構造

パス ファイルは、実際には拡張子が .pkpass の ZIP アーカイブで、特定の JSON ファイル (必須)、さまざまな画像ファイル (省略可能)、ローカライズされた文字列 (省略可能) が含まれています。

  • pass.json - 必須。 パスのすべての情報が格納されています。
  • manifest.json - 必須。 シグネチャ ファイルとこのファイル (manifest.json) を除く、パス内の各ファイルの SHA1 ハッシュが含まれます。
  • signature - 必須。 iOS Provisioning Portal で生成された証明書を使用して manifest.json ファイルに署名することによって作成されます。
  • logo.png - 省略可能。
  • background.png - 省略可能。
  • icon.png - 省略可能。
  • ローカライズ可能な文字列ファイル - 省略可能。

パス ファイルのディレクトリ構造を次に示します (これが ZIP アーカイブの内容です)。

Directory structure of a pass file is shown here

pass.json

通常、パスはサーバー上で作成されるため、JSON は形式です。つまり、生成コードは、サーバー上ではプラットフォームに依存しません。 各パスには、次の 3 つの重要な情報が含まれています。

  • teamIdentifier - これにより、生成したすべてのパスが App Store アカウントにリンクされます。 この値は、iOS Provisioning Portal に表示されます。
  • passTypeIdentifier - パスをグループ化するために Provisioning Portal に登録します (複数のタイプを生成する場合)。 たとえば、コーヒー ショップでは、ストア カード パス タイプを作成して顧客がポイントを獲得できるようにするほか、クーポン パス タイプも別途作成して、割引クーポンを作成、配布できるようにする場合があります。 また、同じコーヒー ショップがライブ ミュージック イベントを計画し、そのためのイベント チケット パスを発行することもあります。
  • serialNumber - この passTypeidentifier 内の一意の文字列。 この値はウォレットに対しては非透過的ですが、サーバーとの通信時に特定のパスを追跡するために重要です。

各パスには他にも多数の JSON キーがあります。その例を次に示します。

{
   "passTypeIdentifier":"com.xamarin.passkitdoc.banana",  //Type Identifier (iOS Provisioning Portal)
   "formatVersion":1,                                     //Always 1 (for now)
   "organizationName":"Xamarin",                          //The name which appears on push notifications
   "serialNumber":"12345436XYZ",                          //A number for you to identify this pass
   "teamIdentifier":"XXXAAA1234",                         //Your Team ID
   "description":"Xamarin Demo",                          //
   "foregroundColor":"rgb(54,80,255)",                    //color of the data text (note the syntax)
   "backgroundColor":"rgb(209,255,247)",                  //color of the background
   "labelColor":"rgb(255,15,15)",                         //color of label text and icons
   "logoText":"Banana ",                                  //Text that appears next to logo on top
   "barcode":{                                            //Specification of the barcode (optional)
      "format":"PKBarcodeFormatQR",                       //Format can be QR, Text, Aztec, PDF417
      "message":"FREE-BANANA",                            //What to encode in barcode
      "messageEncoding":"iso-8859-1"                      //Encoding of the message
   },
   "relevantDate":"2012-09-15T15:15Z",                    //When to show pass on screen. ISO8601 formatted.
  /* The following fields are specific to which type of pass. The name of this object specifies the type, e.g., boardingPass below implies this is a boarding pass. Other options include storeCard, generic, coupon, and eventTicket */
   "boardingPass":{
/*headerFields, primaryFields, secondaryFields, and auxiliaryFields are arrays of field object. Each field has a key, label, and value*/
      "headerFields":[          //Header fields appear next to logoText
         {
            "key":"h1-label",   //Must be unique. Used by iOS apps to get the data.
            "label":"H1-label", //Label of the field
            "value":"H1"        //The actual data in the field
         },
         {
            "key":"h2-label",
            "label":"H2-label",
            "value":"H2"
         }
      ],
      "primaryFields":[       //Appearance differs based on pass type
         {
            "key":"p1-label",
            "label":"P1-label",
            "value":"P1"
         }
      ],
      "secondaryFields":[     //Typically appear below primaryFields
         {
            "key":"s1-label",
            "label":"S1-label",
            "value":"S1"
         }
      ],
      "auxiliaryFields":[    //Appear below secondary fields
         {
            "key":"a1-label",
            "label":"A1-label",
            "value":"A1"
         }
      ],
      "transitType":"PKTransitTypeAir"  //Only present in boradingPass type. Value can
                                        //Air, Bus, Boat, or Train. Impacts the picture
                                        //that shows in the middle of the pass.
   }
}

バーコード

サポートされている形式は、PDF417、Aztec、QR の 2D 形式のみです。 Apple によると、1D バーコードは、バックライト付きの携帯電話画面のスキャンには不向きです。

バーコードの下に表示する代替テキストは省略可能です。一部の販売者は、読み取りと入力を手動で行うことを望んでいます。

ISO-8859-1 エンコードは、パスを読み取るスキャン システムで使用される最も一般的なチェックです。

関連性 (ロック画面)

パスをロック画面に表示させるデータは次の 2 種類です。

場所

パスには、顧客が頻繁に訪れる店舗、映画館、空港など、最大 10 か所を指定できます。 顧客がコンパニオン アプリを使用してこれらの場所を設定することも、プロバイダーが (顧客の承諾を得て収集した) 使用状況データから場所を決定することもできます。

パスがロック画面に表示されると、フェンスが計算され、ユーザーがエリアを離れるとパスはロック画面から消えます。 半径は、不正使用を防ぐためにパス スタイルに関連付けられています。

日付と時間

パスに指定できる日付と時刻は 1 つだけです。 日付と時刻は、搭乗券やイベント チケットのリマインダーをロック画面に表示するのに役立ちます。

プッシュ通知または PassKit API を使用して更新できるため、日付と時刻は、何度も使用するチケット (劇場やスポーツ会場へのシーズン チケットなど) で更新できます。

ローカリゼーション

パスを複数の言語に翻訳するのは、iOS アプリケーションのローカライズと似ています。つまり、.lproj 拡張機能を使用して言語固有のディレクトリを作成し、ローカライズされた要素を内部に配置します。 テキスト翻訳は pass.strings ファイルに入力する必要があり、ローカライズされたイメージはパス ルートで置き換えるイメージと同じ名前にする必要があります。

セキュリティ

パスは、iOS Provisioning Portal で生成したプライベート証明書を使用して署名されます。 パスに署名する手順は次のとおりです。

  1. パス ディレクトリ内の各ファイルに対して SHA1 ハッシュを計算します (manifest.json ファイルや signature ファイルは含めないでください。どちらのファイルも、この段階では存在しないことが必要です)。
  2. 各ファイル名の JSON キー/値リストとしてハッシュを含めて manifest.json を書き込みます。
  3. 証明書を使用して manifest.json ファイルに署名し、signature というファイルに結果を書き込みます。
  4. すべてを ZIP 圧縮し、結果として得られるファイルにファイル拡張子 .pkpass を付けます。

パスの署名には秘密キーが必要であるため、このプロセスは、制御下にあるセキュリティ保護されたサーバーでのみ行う必要があります。 アプリケーションでパスを生成するためにキーを配布しないでください。

構成とセットアップ

このセクションでは、プロビジョニングの詳細を設定し、最初のパスを作成するための手順について説明します。

PassKit のプロビジョニング

パスを使って App Store に入るには、それを開発者アカウントにリンクする必要があります。 これには、次の 2 つの手順が必要です。

  1. パスは、Pass Type ID と呼ばれる一意の識別子を使用して登録する必要があります。
  2. 開発者のデジタル署名を使用してパスに署名するには、有効な証明書を生成する必要があります。

Pass Type ID を作成するには、次の操作を行います。

Pass Type ID を作成する

最初の手順では、サポートされるパスのタイプごとに Pass Type ID を設定します。 Pass ID (または Pass Type ID) は、パスの一意の識別子を作成します。 この ID を使用し、証明書を使用してパスを開発者アカウントにリンクします。

  1. iOS Provisioning Portal の [Certificates, Identifiers, and Profiles] セクションで、[Identifiers] に移動し、[Pass Type IDs] を選択します。 次に、+ ボタンを選択して、新しいパス タイプを作成します。Create a new pass type

  2. パスの説明 (名前) と識別子 (一意の文字列) を指定します。 すべての Pass Type ID は文字列 pass. で始まる必要があります。この例では、pass.com.xamarin.coupon.banana を使用します。Provide a Description and Identifier

  3. [Register] ボタンを押して、パス ID を確認します。

証明書を生成する

この Pass Type ID 用の新しい証明書を作成するには、次の操作を行います。

  1. 新しく作成したパス ID を一覧から選択し、[Edit] をクリックします。Select the new Pass ID from the list

    次に、[Create Certificate…] を選択します。

    Select Create Certificate

  2. 証明書署名要求 (CSR) を作成する手順に従います。

  3. 開発者ポータルの [Continue] ボタンを押し、CSR をアップロードして証明書を生成します。

  4. 証明書をダウンロードし、それをダブルクリックしてキーチェーンにインストールします。

これで、Pass Type ID 用の証明書が作成されました。次のセクションでは、パスを手動で作成する方法について説明します。

ウォレットのプロビジョニングの詳細については、機能の使用に関するガイドを参照してください。

パスを手動で作成する

Pass Type を作成したので、シミュレーターまたはデバイスでテストするパスを手動で作成できます。 パスを作成する手順は次のとおりです。

  • パス ファイルを格納するディレクトリを作成します。
  • 必要なすべてのデータを含む pass.json ファイルを作成します。
  • フォルダーにイメージを含めます (必要な場合)。
  • フォルダー内のすべてのファイルの SHA1 ハッシュを計算し、manifest.json に書き込みます。
  • ダウンロードした証明書 .p12 ファイルを使用して manifest.json に署名します。
  • ディレクトリの内容を ZIP 圧縮し、.pkpass という拡張子で名前を変更します。

この記事のサンプル コードには、パスの生成に使用できるソース ファイルがいくつかあります。 CreateAPassManually ディレクトリの CouponBanana.raw ディレクトリにあるファイルを使用してください。 次のファイルがあります。

These files are present

pass.json を開き、JSON を編集します。 Apple Developer アカウントに合わせて、少なくとも passTypeIdentifierteamIdentifer を更新する必要があります。

"passTypeIdentifier" : "pass.com.xamarin.coupon.banana",
"teamIdentifier" : "?????????",

その後、各ファイルのハッシュを計算し、manifest.json ファイルを作成する必要があります。 最終的には次のようになるはずです。

{
  "icon@2x.png" : "30806547dcc6ee084a90210e2dc042d5d7d92a41",
  "icon.png" : "87e9ffb203beb2cce5de76113f8e9503aeab6ecc",
  "pass.json" : "c83cd1441c17ecc6c5911bae530d54500f57d9eb",
  "logo.png" : "b3cd8a488b0674ef4e7d941d5edbb4b5b0e6823f",
  "logo@2x.png" : "3ccd214765507f9eab7244acc54cc4ac733baf87"
}

次に、この Pass Type ID について生成された証明書 (.p12 ファイル) を使用して、このファイルの署名を生成する必要があります。

Mac 上で署名する

Apple ダウンロード サイトからウォレット シードのサポート資料をダウンロードしてください。 signpass ツールを使用して、フォルダーをパスに変換します (これにより、さらに SHA1 ハッシュが計算され、出力が .pkpass ファイルに ZIP 圧縮されます)。

テスト

これらのツールの出力を調べる (ファイル名を .zip に設定して開く) と、次のファイルが表示されます (manifest.jsonsignature ファイルが追加されている点に注意してください)。

Examining the output of these tools

署名、ZIP 圧縮、ファイル名の変更 (BananaCoupon.pkpass など) が完了したら、シミュレーターにドラッグしてテストするか、自分宛てにメールを送信して実際のデバイスで取得できます。 次のように、パスを追加する画面が表示されます。

Add the pass screen

通常、このプロセスはサーバー上で自動化されますが、バックエンド サーバーのサポートを必要としない、クーポンのみを作成する小規模企業などは、手動でパスの作成を行うこともできます。

ウォレット

ウォレットは、PassKit エコシステムの中心的な部分です。 以下のスクリーンショットは、空のウォレットのほか、パス リストと個々のパスの外観を示しています。

This screenshot shows the empty Wallet, and how the pass list and individual passes look

ウォレットの機能は次のとおりです。

  • ここは、スキャンするバーコードと一緒にパスがレンダリングされる唯一の場所です。
  • ユーザーは、設定を変更して更新できます。 プッシュ通知 (有効な場合) によってパス内のデータが更新されます。
  • ユーザーは、ロック画面の統合を有効または無効にすることができます。 有効にすると、パスに埋め込まれた関連する時刻と場所のデータに基づいて、パスがロック画面に自動的に表示されます。
  • パスの逆側では、web-server-URL がパス JSON で指定されている場合、「引っ張って更新」がサポートされます。
  • パス JSON でアプリの ID が指定されている場合は、コンパニオン アプリを開く (またはダウンロードする) ことができます。
  • パスは (細断を示すアニメーション付きで) 削除できます。

ウォレットにパスを追加する

パスは、次の方法でウォレットに追加できます。

  • コンジット アプリ - これらはパスを直接操作するのではなく、単にパス ファイルをロードし、ウォレットに追加するオプションをユーザーに提示します。

  • コンパニオン アプリ - これらは、パスを配布し、それらを参照または編集するための追加機能を提供するためにプロバイダーによって記述されています。 Xamarin.iOS アプリケーションは、PassKit API に完全にアクセスしてパスを作成および操作できます。 その後、PKAddPassesViewController 使用してパスをウォレットに追加できます。 このプロセスの詳細については、このドキュメントの「コンパニオン アプリケーション」セクションを参照してください。

コンジット アプリケーション

コンジット アプリケーションは、ユーザーに代わってパスを受け取ることができる中間アプリです。これは、コンテンツ タイプを認識し、ウォレットに追加する機能を提供するようにプログラミングする必要があります。 コンジット アプリの例を次に示します。

  • メール - 添付ファイルをパスとして認識します。
  • Safari - パスの URL リンクがクリックされたときに、パスのコンテンツ タイプを認識します。
  • その他のカスタム アプリ - 添付ファイルを受信したり、リンクを開いたりするアプリ (ソーシャル メディア クライアント、メール リーダーなど)。

このスクリーンショットは、iOS 6 のメールが、どのようにパスの添付ファイルを認識し、(タッチされたときに) 追加機能をウォレットに表示するかを示しています。

This screenshot shows how Mail in iOS 6 recognizes a pass attachment

This screenshot shows how Mail offers to add a pass attachment to Wallet

パスのコンジットになる可能性があるアプリを作成する場合は、次の方法で認識できます。

  • ファイル拡張子 - .pkpass
  • MIME タイプ - application/vnd.apple.pkpass
  • UTI - com.apple.pkpass

コンジット アプリケーションの基本的な操作は、パス ファイルを取得し、PassKit の PKAddPassesViewController を呼び出して、ウォレットにパスを追加するオプションをユーザーに提供することです。 このビュー コントローラーの実装については、次の「コンパニオン アプリケーション」セクションで説明します。

コンジット アプリケーションは、コンパニオン アプリケーションのように、特定の Pass Type ID に対してプロビジョニングする必要はありません。

コンパニオン アプリケーション

コンパニオン アプリケーションには、パスの作成、Pass に関連付けられた情報の更新、アプリケーションに関連付けられているパスの管理など、パスを操作するための追加機能が用意されています。

コンパニオン アプリケーションで、ウォレットの機能を複製しないでください。 これは、パスを表示してスキャンすることを目的とはしていません。

このセクションの残りの部分では、PassKit と対話する基本的なコンパニオン アプリを作成する方法について説明します。

プロビジョニング

ウォレットはストア テクノロジであるため、アプリケーションは個別にプロビジョニングする必要があり、Team Provisioning Profile や Wildcard App ID を使用することはできません。 ウォレット アプリケーションの一意の App ID と Provisioning Profile を作成するには、機能の使用に関するガイドを参照してください。

権利

Entitlements.plist ファイルは、最近のすべての Xamarin.iOS プロジェクトに含める必要があります。 新しい Entitlements.plist ファイルを追加するには、エンタイトルメントの使用に関するガイドの手順に従います。

エンタイトルメントを設定するには、次の操作を行います。

Solution Pad の Entitlements.plist ファイルをダブルクリックして、Entitlements.plist エディターを開きます。

Entitlements.plst editor

[Wallet] セクションで、[Enable Wallet] オプションを選択します。

Enable wallet entitlement

既定のオプションは、アプリですべてのパス タイプを許可することです。 ただし、アプリを制限し、チーム パス タイプのサブセットのみを許可することはできます。 これを有効にするには、[Allow subset of team pass types] を選択し、許可するサブセットの Pass Type ID を入力します。

デバッグ

アプリケーションのデプロイで問題が発生した場合は、正しい Provisioning Profile を使用していること、[iPhone Bundle Signing] オプションで Entitlements.plistカスタム エンタイトルメント ファイルとして選択されていることを確認してください。

デプロイ時にこのエラーが発生した場合:

Installation failed: Your code signing/provisioning profiles are not correctly configured (error: 0xe8008016)

この場合、pass-type-identifiers エンタイトルメント配列が間違っています (または Provisioning Profile と一致していません)。 Pass Type ID と Team ID が正しいことを確認します。

クラス

アプリからパスへのアクセスには、次の PassKit クラスを使用できます。

  • PKPass - パスのインスタンス。
  • PKPassLibrary - デバイス上のパスにアクセスするための API を提供します。
  • PKAddPassesViewController - ユーザーがウォレットに保存するパスを表示するために使用されます。
  • PKAddPassesViewControllerDelegate - Xamarin.iOS 開発者

この記事のサンプル コードにある PassLibrary プロジェクトを参照してください。 これは、ウォレット コンパニオン アプリケーションで必要となる次の一般的な機能を示します。

ウォレットが使用可能であることを確認する

ウォレットは iPad では使用できないため、アプリケーションは PassKit 機能にアクセスする前に確認する必要があります。

if (PKPassLibrary.IsAvailable) {
    // create an instance and do stuff...
}

パス ライブラリ インスタンスを作成する

PassKit ライブラリはシングルトンではありません。アプリケーションは、PassKit API にアクセスするためのインスタンスを作成し、格納する必要があります。

if (PKPassLibrary.IsAvailable) {
    library = new PKPassLibrary ();
    // do stuff...
}

パスの一覧を取得する

アプリケーションは、ライブラリからパスの一覧を要求できます。 この一覧は PassKit によって自動的にフィルター処理されるため、自分の Team ID で作成され、エンタイトルメントに一覧表示されているパスのみが表示されます。

var passes = library.GetPasses ();  // returns PKPass[]

シミュレーターでは返されるパスの一覧がフィルター処理されないため、この方法は、常に実際のデバイスでテストする必要があります。 この一覧は UITableView に表示できます。 サンプル アプリは、2 つのクーポンが追加された後、次のようになります。

The sample app look like this after two coupons have been added

パスを表示する

コンパニオン アプリ内でのパスのレンダリングでは、使用可能な一連の情報は限られています。

コード例で示すように、パスの一覧を表示するには、この一連の標準プロパティから選択します。

string passInfo =
                "Desc:" + pass.LocalizedDescription
                + "\nOrg:" + pass.OrganizationName
                + "\nID:" + pass.PassTypeIdentifier
                + "\nDate:" + pass.RelevantDate
                + "\nWSUrl:" + pass.WebServiceUrl
                + "\n#" + pass.SerialNumber
                + "\nPassUrl:" + pass.PassUrl;

この文字列は、サンプル内のアラートとして表示されます。

The Coupon Selected alert in the sample

また、LocalizedValueForFieldKey() メソッドを使用して、設計したパス内のフィールドからデータを取得することもできます (どのフィールドがあるかがわかっているため)。 これは、コード例には表示されません。

ファイルからパスを読み込む

パスはユーザーのアクセス許可があるウォレットにのみ追加できるため、ビュー コントローラーを提示して決定できるようにする必要があります。 このコードは、この例の [追加] ボタンで使用されています。これは、アプリに埋め込まれている事前構築済みのパスを読み込みます (これを署名したパスに置き換える必要があります)。

NSData nsdata;
using ( FileStream oStream = File.Open (newFilePath, FileMode.Open ) ) {
        nsdata = NSData.FromStream ( oStream );
}
var err = new NSError(new NSString("42"), -42);
var newPass = new PKPass(nsdata,out err);
var pkapvc = new PKAddPassesViewController(newPass);
NavigationController.PresentModalViewController (pkapvc, true);

パスには、[追加][キャンセル] オプションが表示されます。

The pass presented with Add and Cancel options

既存のパスを置換する

既存のパスの置換には、ユーザーのアクセス許可は必要ありませんが、パスがまだない場合は失敗します。

if (library.Contains (newPass)) {
     library.Replace (newPass);
}

パスを編集する

PKPass は変更できないため、コード内の pass オブジェクトを更新することはできません。 パス内のデータを変更するには、アプリケーションが、パスの記録を保持し、ダウンロードした更新値で新しいパス ファイルを生成できる Web サーバーにアクセスできる必要があります。

パスは、非公開で安全な証明書を使用して署名する必要があるため、パス ファイルの作成はサーバーで行う必要があります。

更新されたパス ファイルが生成されたら、Replace メソッドを使用してデバイス上の以前のデータを上書きします。

スキャン用のパスを表示する

すでに説明したとおり、スキャン用のパスを表示できるのはウォレットのみです。 パスは、次のように OpenUrl メソッドを使用して表示できます。

UIApplication.SharedApplication.OpenUrl (p.PassUrl);

変更の通知を受信する

アプリケーションは、PKPassLibraryDidChangeNotification を使用して、パス ライブラリに加えられた変更をリッスンできます。 変更は、バックグラウンドで更新をトリガーする通知によって発生する可能性があるため、アプリ上でリッスンすることをお勧めします。

noteCenter = NSNotificationCenter.DefaultCenter.AddObserver (PKPassLibrary.DidChangeNotification, (not) => {
    BeginInvokeOnMainThread (() => {
        new UIAlertView("Pass Library Changed", "Notification Received", null, "OK", null).Show();
        // refresh the list
        var passlist = library.GetPasses ();
        table.Source = new TableSource (passlist, library);
        table.ReloadData ();
    });
}, library);  // IMPORTANT: must pass the library in

PKPassLibrary はシングルトンではないため、通知に登録するときにはライブラリ インスタンスを渡すことが重要です。

サーバー処理

PassKit をサポートするサーバー アプリケーションの作成の詳細については、この入門記事では説明しません。

dotnet-passbook オープン ソース C# サーバーサイド コードを参照してください。

プッシュ通知

プッシュ通知を使用してパスを更新する方法の詳細については、この入門記事では説明しません。

更新が必要な場合は、Apple が定義する REST に似た API を実装して、ウォレットからの Web 要求に応答する必要があります。

詳細については、Apple のパスの更新に関するガイドを参照してください。

まとめ

この記事では、PassKit を紹介し、それが有用な理由をいくつか取り上げ、完全な PassKit ソリューションに実装する必要があるさまざまな要素について説明しました。 Apple Developer アカウントを構成してパスを作成するために必要な手順、パスを手動で作成するプロセス、Xamarin.iOS アプリケーションから PassKit API にアクセスする方法についても説明しました。