iOS6の新機能の1つにPassbookというのがあります。iPhoneをイベントチケット、交通機関搭乗チケット、ポイントカード、プリペイドカードなどとして利用するもので、サービス毎に個別アプリをインストールしなくても、Passbookアプリの中にそれらをまとめることができます。現行のiPhoneはFelicaやNFCといったおサイフケータイ系ハードを搭載していませんが、画面に表示したバーコードをレジのリーダーに読ませることで自動入力することができます。イベントや搭乗の時間や場所に近づいたら通知センターで知らせたり、それらの変更やプリペイドカードの残高をネットワーク経由でプッシュ更新したりできます。お財布が薄くなる上に様々なリマインド機能もあるのでどんどん活用してみたいのですが、残念ながら日本ではまだ対応サービスがあまりなく、ぐるなびやHOT PEPPERなどの飲食店クーポン程度。そこで、今日「劇場版 魔法少女まどか★マギカ」に行くのを機会に、イベントチケットの自炊をしてみました。
■Passbookパス概要
- テキストファイル(JSON形式)+各種画像ファイルで構成
- iOS Developer Program(有料)の開発者証明書で署名しないと実機にインストールできない
- プッシュ更新には専用サーバーを用意する必要がある
- 配布はWebからダウンロードやメール添付、もしくはアプリ内で生成する方法がある
という感じ。開発者登録が必要なのはちと残念ですね。とりあえず今回はサーバー更新は必要ないので、「映画館近くまで行ったら発券用の予約番号を通知してくれる」ということを目標にしてみます。
■Apple配布のひな形を改変する
参考資料としては、Appleがこちらで公開している「Passbook プログラミングガイド」を使います。P.8に「開発者向け素材のダウンロード」というリンクがあり、そこを辿ってpassbook_materials.dmgをダウンロードします(要開発者ログインID)。マウントするとPassesフォルダにイベントチケット、クーポン券など目的別のサンプルがあるので、フォルダごとどこか読み書き可能な領域にコピーします。今回はEvent.rawフォルダをコピーして使用。pass.jsonというテキストファイルがメインの定義ファイルとなります。というかこれ以外にはあと画像があるのみです。pass.jsonでハマったのは、以下。
passTypeIdentifier: developer.apple.comであらかじめ取得したpass.com.hoge.passkitみたいなIDを指定。取得方法はアプリIDと同じなので開発者なら迷わず取れるでしょう。
teamIdentifier: ガイドの和訳がいけてないので紛らわしいですが、英数字10桁のアプリIDの前につくアレです。
この2つが証明書のものと同じでないとエラーになります(iPhone上で表示まではいくけど取り込めない)。
serialNumber: シリアルナンバーです。これとPassTypeIdentifierが同一なら同じパスの更新と見なされ上書きされるようです。
webServiceURL: 今回は使用しないのでダミーでいいんですが、https://にしておかないとやはりエラーになって取り込めません。一応無駄パケットはとぶかもなので、自前サーバーなど迷惑のかからないところを指定します。もしかするとこの行自体なくてもいけるのかな?
以下、上のサンプル写真と対比させながら指定していきます。
logoText: 「チケット購入」となっている部分です。Passbookに複数のチケットが入って一覧した時にここが見えるので、もう少し具体的な名前にしておいた方が良かったなと思いました。
relevantDate: イベントや搭乗の日時です。注意すべきは「2012-10-08T16:30+09:00」のようにタイムゾーン指定(この場合は+09:00)が必要な点。また+9:00ではダメで+09:00とする必要があります。
locations: 対象地点です。緯度と経度を指定します。relevantTextフィールドを追加しておくと、通知画面でのメッセージになります(冒頭画像でいう「映画館に近づきました」の部分)。
barcode: バーコード生成部分です。今回は不要ですが一応発券番号を出して見ました。messageが実際のコード。下に数字も出したい場合は、altTextという項目を追加します。行を追加する時はカンマに気をつけましょう。数字はいるけどバーコードが不要な場合は後述のauxiliaryFields辺りに表示しておけば良いでしょう。
organizationNameやdescriptionは券面には反映されないようです。foregroundColor(文字色)、backgroundColor(背景色)はそれぞれRGBの値を0~255で指定します。
eventTicketの下に、primaryField、secondaryFields、auxiliaryFields、backFieldsなどがあり、券面に表示される文字列を指定できます。keyは適当でいいと思いますが重複しない方がヨサゲ。labelが見出しでvalueが内容です。フォントサイズの指定がよくわからず、残念ながら作品名が途中までしか表示できませんでした。サムネイルを無くす手もあるかも。
一応、eventTicket部分をそのまま貼っておきます。auxiliaryFieldsはひな形にはなかったので追加しました。
"eventTicket" : {
"primaryFields" : [
{
"key" : "event",
"label" : "作品名",
"value" : "劇場版 魔法少女まどか★マギカ"
}
],
"secondaryFields" : [
{
"key" : "loc",
"label" : "劇場",

60; "value" : "ユナイテッドシネマ豊橋18"
}
],
"auxiliaryFields" : [
{
"key" : "time",
"label" : "上映日時",
"value" : "2012-10-06 21:00-23:30"
}
],
"backFields" : [
{
"key" : "terms",
"label" : "使用仕様上の注意",
"value" : "試験的に自作したPassbookチケットです。"
},
{
"key" : "website",
"label" : "劇場アクセス",
"value" : "http://www.unitedcinemas.jp/toyohashi/about-theater.html"
}
]
}
■画像について
thumnail.png: 画面右側に出るサムネイルです。サンプルのサイズは112×142でした。
background.png: 背景です。イベントチケットの場合は自動的にぼかしがかかります。サンプルではthumnail.pngと同じもののようでしたので、今回も名前だけかえてコピーして使いました。ちと文字が読みづらいのでもっとスッキリしたものを用意した方がヨサゲですね。
icon.png: 通知センターに表示される時に使われます。29×29。写真一枚目のまどかの顔。
logo.png: 写真中の左上にあるアップルロゴです。30×35。今回はそのまま使用しました。
またそれぞれにRetinaディスプレイ用に縦横倍のサイズのものが必要で、ファイル名の最後に「@2x」をつけます。
用意するデータはたったこれだけ。pass.jsonと画像4種x2サイズの9ファイル。これをmadomagi.pass.rawなどと名付けたフォルダに集めておきます。
■電子署名する
先にも書いた通り、iOS Developer Programに加入していることが前提です。まず「キーチェーンアクセス」を起動し、証明書アシスタント->認証局に証明書を要求…を開き、「ディスクに保存」でCertificateSigningRequest.certSigningRequest(いわゆるCSR)というファイルを生成します。これを使ってdeveloper.apple.comで証明書を取得(この辺りは開発者なら手慣れてるでしょうから割愛)。ダウンロードした証明書をキーチェーンアクセスに登録しておきます(CSRは削除してOK)。
次にサイン用のCUIツールsignpassをビルドします。冒頭のキットにXcode用プロジェクトが含まれているので開いてビルドするだけです。出来上がった実行バイナリの見つけ方はガイドに書かれています。ここまでできたらターミナルから、
signpass –p madomagi.pass.raw
とするだけ。問題がなければmadomagi.pass.pkpassというファイルが出来上がります。これがチケットです。
ちなみに、Webサーバーでリアルタイムに生成した場合は、RubyやPHP用の署名ツール実装もあるみたいです。iOSアプリ内で生成する時はPasskitというフレームワークを利用できます。
■Webで配布する
これを単にメール添付でiPhoneで送る分には特に問題ないですが、Webサーバーに置いてSafariからダウンロードする場合は、サーバー側にpkpassという拡張子のMIMEタイプを設定しておく必要があります。Apacheの場合、適切な場所に以下を追記します。今回は/etc/mime.typesに追加しました。
application/vnd.apple.pkpass pkpass
なお、ダウンロードでエラーになったり、表示はされるのにPassbookに取り込めない場合は何かしらエラーになってます。実機ならXcodeのコンソールで見えられます。またiOSシミュレーターに.pkpassファイルをドロップしても検証でき、その際はOSXの「コンソール」アプリでエラーメッセージが読めるので捗りますよ。
■もっと簡単に作ってみたい!
この記事を書き始めてから気付いたんですが、ここにWebフォームで簡単に生成できるジェネレーターがありましたw。もっと簡単にやってみたいって人は挑戦してみて下さい。とはいえ、自分の会員番号や予約番号を外部サーバーにアップするのは自己責任で。あと開発者証明書はどのみち用意しないとダメっぽいです。
べ、別に技術検証したかったんだから悔しくなんかないんだからねっ!
開発者IDが必須なのは残念ですが、それさえクリアしてしまえば割と簡単に自炊できることがわかりました。身内のパーティや勉強会などで配布してドヤ顔するのもアリじゃないでしょうか。「入っておくのエレベーターで○階の受付までいって、係に○○と伝えて下さい」みたいな情報を建物前で慌ててメールを探らせることなく自動通知できるなんて素敵ですやん?
当面はiOSしか利用できないので、一般企業がどれくらい参入するのかは未知数ですね。