13新卒エンジニアの古川です。今回で二回目の記事です!
最近、クーポンやイベントチケットを一元管理できる、iOSのPassbookという機能が注目されてきました。さらに、Railsの4.0が正式リリースされたようです。
ということで、Rails4.0でPassbookの実装をしてみたので紹介します!
実装環境
フレームワーク:Rails 4.0
プログラミング言語:Ruby 2.0.0-p195
DBMS:MySQL 5.1.69
使用するライブラリ
Passbookを実装するにあたって、使用するライブラリは以下の2つです!
xl-passbook-ruby
RailsでPassbookの環境を実装するのに便利なライブラリです。ただし、プッシュ通知は別途実装する必要があります。
Grocer
Passbookのプッシュ通知に使用します。
これによって以下のことが一通り実装できます。
・Passbookのダウンロード・登録
・iPhone上でのPassbook登録・削除時の通知処理
・Passbook変更時のプッシュ通知
実装に必要なもの
実装の前に、まずは以下のものを用意してください。
①Passbook用のユーザの秘密鍵と電子証明書(P12ファイル)
iOS Dev CenterでPassbookが登録されたときにダウンロードできる証明書ファイルからキーチェーンアクセスを用いて変換します。今回ファイル名はpass.test.example.p12とします。
②P12ファイルを生成したときのパスワード
①を生成する際に入力するパスワード
③PassbookのID
iOS Dev Centerで登録したPassbookのIdentifier(今回はpass.test.exampleとします)
④Passbookの部署ID
キーチェーンアクセスでインストールされたPassbook証明書の詳細で確認できます。
⑤wwdr.pem
つぎのページで証明書ファイルをダウンロードしたあと、キーチェーンアクセスを用いて変換し、取得します。
http://developer.apple.com/certificationauthority/AppleWWDRCA.cer
Railsプロジェクトの作成
まずRailsプロジェクトを作成し、下準備します。
(1) まずはこのコマンドで、プロジェクトを作成します。
rails new passbook_example -d mysql
(2) config/database.ymlを設定します。
development:
adapter: mysql2
encoding: utf8
database: passbook_example_development
pool: 5
username: MySQLのユーザネーム
password: MySQLのパスワード
socket: /var/lib/mysql/mysql.sock
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: mysql2
encoding: utf8
database: passbook_example_test
pool: 5
username: MySQLのユーザネーム
password: MySQLのパスワード
socket: /var/lib/mysql/mysql.sock
production:
adapter: mysql2
encoding: utf8
database: passbook_example_production
pool: 5
username: MySQLのユーザネーム
password: MySQLのパスワード
socket: /var/lib/mysql/mysql.sock
(3) Gemfileに必要なGemを追加します。(この部分はバージョン依存が強く、たびたび嵌りました)
# Rails4を動作させるためには、以下の3つのGemが必要でした。
# therubyracer・rb-readlineはバージョン指定しないとエラーがでてしまいます。
gem 'execjs'
gem 'therubyracer' , '=0.10.0'
gem 'rb-readline', '= 0.5.0', require: 'readline'
# デフォルトのxl-passbook-rubyは、Rails4のルーティングに対応していないので、以下を使用します。
gem 'passbook-ruby', git: 'https://github.com/Sjors/xl-passbook-ruby.git', branch: 'rails4'
# 現在1.0.0に更新されており、passbook-rubyが動作しなかったため0.9.9を指定しています。
gem 'rubyzip' , '=0.9.9'
# プッシュ通知に使用します
gem 'grocer'
(4)Gemfileの更新を行います。
cd passbook_example
bundle install
これで下準備は完了しました。
Passbookの実装
以下のフォルダを作成します。
mkdir data/certificates -p
上記のフォルダに、実装時に必要なもので記述した①pass.test.example.p12と⑤wwdr.pemを入れます。
あとは次のコマンドを実行するだけです。
rails g passbook:config
# ticketは任意のモデル名
# identifierは③のPassbookのID
# team_idは④Passbookの部署ID
# passbook_certification_file はpass.test.example.p12へのパス
# 今回は「data/certificates/pass.test.example.p12」と入力します。
# cert_passwordは②P12ファイルを生成したときのパスワード
rails g passbook:pkpass ticket [identifier] [team_id] [passbook_certification_file] [cert_password]
エラーがなく無事に作成されましたら、以下のコマンドでデータベースを構築します。
rake db:create
rake db:migrate
つぎに新たに作成されたapp/models/ticket.rbを次のように変更します。この変更をしなければPassbookの登録ができませんのでご注意ください。
def update_json pass_json
pass_json['authenticationToken'] = authentication_token
pass_json['serialNumber'] = serial_number
#don't forget to change the URL to whatever address your server is at
pass_json['webServiceURL'] = "ここにグローバルIPアドレスを入力します。プライベートIPアドレスは使用できません。"
#add more customization to your passbook's JSON right here
end
この時点でプッシュ通知以外は実装されました<(`・ω・´)
プッシュ通知の実装
今回はすぐに試したいということで、以前編集長が紹介していましたGrocerを用いて実装しました。
まずはコントローラを作成します。
rails g controller passbook_user push_notification
①pass.test.example.p12からpass.test.example.pemを作成します。
cd data/certificates
openssl pkcs12 -in pass.test.example.p12 -clcerts -nokeys -out pass.test.example.pem
作成時にパスワードが要求されますので、②P12ファイルを生成したときのパスワードを入力します。
/app/controllers/passbook_user.rbに対して以下の実装を行います。
def push_notification
require 'grocer'
pusher = Grocer.pusher(
certificate: Rails.root.to_s + "/data/certifications/pass.test.example.pem",
passphrase: '②P12ファイルを生成したときのパスワード',
gateway: "gateway.push.apple.com",
port: 2195,
retries: 3
)
tokens = Passbook::Registration.all
tokens.each do |token|
notification = Grocer::PassbookNotification.new(
device_token: token.push_token,
)
#update ticket
Ticket.where({serial_number: token.serial_number}).first().touch
pusher.push(notification)
end
end
念のため、/app/views/user_passbook/push_notification.html.erbを以下のように変更します。
<h1>プッシュ通知完了</h1>
これでPassbookに必要な環境全て整いました!お疲れ様でした!!
動作確認
まず、/data/templates/pass.test.example/pass.jsonを以下のように修正します。
・・・
"barcode" : {
"message" : "34534636",
"format" : "PKBarcodeFormatPDF417",
"messageEncoding" : "iso-8859-1"
},
"organizationName" : "1234ABCD",
"description" : "テストPassbookです。",
"logoText" : "AdwaysExample",
"foregroundColor" : "rgb(0, 0, 0)",
"backgroundColor" : "rgb(255,255,255)",
"eventTicket" : {
"headerFields" : [
],
"primaryFields" : [
{
"key" : "title",
"label" : "",
"value" : "Hoge Foobar"
}
],
"secondaryFields" : [
{
"label" : "更新日",
"key" : "update_time",
"value" : "2013/08/19",
"changeMessage" : " 更新日が変更されました %@"
}
],
"auxiliaryFields" : [],
"backFields" : [
{
"key" : "description",
"label" : "概要説明",
"value" : " これはサンプルです!"
}
]
}
}
以下のコマンドでrailsのサーバーを起動します。(このコマンドはスーパーユーザしか実行できませんのでご注意を)
rails s -p 80
通常Passbookとの通信はHTTPSだけに制限されていますが、動作確認のためHTTPでも通信できるようにiPhoneの設定を変更します。
設定方法は次のとおりです。
(1)まずiPhoneをMacにつなげて接続し、Xcodeを立ち上げます。
(2)Organizerに切り替え、接続しているiPhoneを選択します。
(3)メイン画面にある「Use for development」ボタンをクリックします。
(4)iPhoneの設定に「デベロッパ」が表示されます。「デベロッパ」を選択すると表示される「Allow HTTP Services」をオンに切り替えます。
ここで、実際にダウンロードを行ってみます。
http://実装したwebサーバのIPアドレス/v1/passes/ticket
表示されました!!
つぎに「追加」ボタンを押してみましょう。うまくいけば以下のような感じでアニメーションが表示されます。こうならなければ、設定にミスがあります。部署名やWebServiceの項目に誤りがないか、HTTP通信の許可をとっているかどうか確認してください。(ちなみにこれを解決するのに数時間とられたのは内緒です)
つぎにプッシュ通知を行ってみます。
まずは/data/templates/pass.test.example/pass.jsonをいじっておきます。
・・・
"barcode" : {
"message" : "34534636",
"format" : "PKBarcodeFormatPDF417",
"messageEncoding" : "iso-8859-1"
},
"organizationName" : "1234ABCD",
"description" : "テストPassbookです。",
"logoText" : "AdwaysExample",
"foregroundColor" : "rgb(0, 0, 0)",
"backgroundColor" : "rgb(255,255,255)",
"eventTicket" : {
"headerFields" : [
],
"primaryFields" : [
{
"key" : "title",
"label" : "",
"value" : "Hoge Foobar"
}
],
"secondaryFields" : [
{
"label" : "更新日",
"key" : "update_time",
"value" : "2013/08/21",
"changeMessage" : " 更新日が変更されました %@"
}
],
"auxiliaryFields" : [],
"backFields" : [
{
"key" : "description",
"label" : "概要説明",
"value" : " これはサンプルです!"
}
]
}
}
以下の URL にアクセスして、実際にプッシュ通知を行ってみましょう。
http://実装したwebサーバのIPアドレス/user_passbook/push_notification
うまくいけば、こんな感じに更新されます。
これでPassbookの一通りの機能が実装したことを確認できました。
振り返り
passbook-rubyによる実装はそこまで難しくないです。
ただ、
Passbookの証明書云々を用意するのと、Mac環境の用意が面倒でした。。。
(Mac環境用意するのに1ヶ月ほどかかった自分がいます(´・ω・`)
あとはWebServiceをグローバルIPで公開するのと、HTTP通信を許可するためにiPhoneのデベロッパー設定を変える部分に注意が必要です。(これに気づくのに数時間かかりました。。。
逆にそれらさえ気をつければ、手軽に実装できます。
一度は試してみてはいかかでしょうか?
以上です。今回は実装手順が長いため、長文になってしまいました(´・ω・`)