jpmobile + Rails 2.3.5 で作る携帯サイト入門 【後編】
初稿:2010-03-16
概要
前回は jpmobile の基本的な機能を使った携帯サイトの構築方法を解説しました.今回は iPhone や Android といった新しいキャリア・端末への対応する方法を解説します.
Rails 2.3.5 について
2010年2月中旬現在の最新版は Rails 2.3.5 ですので,本記事では全て 2.3.5
を用いています.そのためタイトルが前回と少し変更されていますが,基本的にどちらのバージョンでも実行可能です.
jpmobile とは
Ruby 札幌所属の darashi さんが制作されている,携帯電話特有の機能を Ruby on Rails で利用するためのプラグインです.
ここで私は主に Rails 2.3 以降の対応と携帯メールの送受信機能の新規開発を担当しています.
jpmobile の機種判別の仕組み
今回は jpmobile で iPhone や Android といった新しい端末への対応方法を解説したいと思います.
その前にまずは,jpmobile がどうやって機種・端末を判定しているのかを見てみましょう.
jpmobile では「キャリアのクラス」「request.mobile.docomo? などのメソッド」「ビューの切り替え」という 3 つの機能で機種・端末の判定をしています.
キャリアのクラスを取得する
jpmobile では各キャリアごとに専用のクラスを用意しており,ActionController の request.mobile を通じてそのインスタンスを取得することができます.
キャリアのクラスは,例えば docomo であれば lib/mobile/docomo.rb で定義されていて,各ファイルは autoload によって読み込まれるようになっています.
request.mobile は lib/jpmobile/request_with_mobile.rb で定義されている mobile メソッドです.
- lib/jpmobile/request_with_mobile.rb の抜粋
Jpmobile::Mobile.carriers は lib/jpmobile.rb に書かれているように,その時点で Jpmobile::Mobile で定義されている定数,つまりクラスの一覧を返します.request.mobile が呼ばれたときには,
いま定義されているキャリアのクラスのそれぞれにおいて,アクセスのあったユーザエージェントが,そのユーザエージェントの正規表現とマッチするかどうかを判定して,マッチしたクラスのインスタンスを返す
という処理を実行しています.これで適切なクラスのインスタンスが得られます.
この一連の処理は lib/jpmobile/hook_request.rb によって Rails に組み込まれます.
- lib/jpmobile/hook_request.rb
request.mobile.docomo? というメソッド
jpmobile では,例えば docomo からのアクセスであれば request.mobile.docomo? というメソッドが true を返す仕組みがあります.
これは lib/jpmobile/mobile/abstract_mobile.rb で定義されています.
さきほどのキャリアのクラスは,この Jpmobile::AbstractMobile を継承しているので,request.mobile.docomo? というメソッドを使うことができるようになります.
ビューの切り替え
前回説明したように,携帯端末と PC とでビューを切り替えるときに,たとえば index.html.erb / index_mobile.html.erb / index_mobile_docomo.html.erb の 3 つのファイルを用意することで,PC / 携帯 / docomo の表示を切り替えることができます.
この処理は lib/jpmobile/hook_action_view.rb と lib/jpmobile/hook_action_controller.rb で行われています.
Rails ではコントローラのアクション実行後や render メソッドを明示的に呼び出した場合などに,目的にあったビューファイルを選択するために,ActionView::PathSet#find_template メソッドを呼び出しています.
jpmobile ではこの部分をフックして,キャリアに応じた独自のファイルが存在すればそれを,そうでなければ Rails 本来の処理を行うように変更しています.
iPhone を判別する
jpmobile でのキャリア判定処理は以上のようになっています.
では実際に iPhone を例にとって追加してみましょう.今回はプラグインは変更せずに追加してみたいと思います.
まずは前回を参考に jpmobile がインストールされた Rails アプリケーションを作成しておきます.
iPhone クラスの作成
まずは iPhone クラスを作成します.ここでは lib/jpmobile/mobile/softbank.rb をベースにしていきますが,Jphone / Vodafone クラスは今回は無関係なので削除します.
さらに簡単のために位置情報と端末 ID も削除します.必要であればここに個別の実装を追加してください.
そしてユーザエージェントの正規表現を iPhone 用に書き換え,クラス名を Iphone に変更すればクラスファイルの準備は完了です.
このファイルを RAILS_ROOT/lib/jpmobile/mobile/iphone.rb として保存します.
ユーザエージェントをかなり簡単にしましたが,ここも適宜書き換えてください.
iPhone クラスの組み込み
さてクラスを作ってもそれだけでは jpmobile は判定して動作してくれません.
判定させるために Jpmobile::Mobile.carriers に Iphone クラスを追加します.
この処理は config/environment.rb に追加します.
iPhone 用ビューの作成
それではテストしてみましょう.まずは TopController を作成します.
判定されていることを見るだけなので,index アクションのみ設定します.
- app/controllers/top_controller.rb
次に PC 用 / 携帯用 / iPhone 用の 3 つのビューを作成します.
ファイル名はそれぞれ index.html.erb / index_mobile.html.erb / index_mobile_iphone.html.erb とします.
- app/views/top/index.html.erb
- app/views/top/index_mobile.html.erb
- app/views/top/index_mobile_iphone.html.erb
サーバを起動してブラウザで確認してみてください.Firefox であれば FireMobileSimulator を使って PC / 携帯 / iPhone でアクセスすると,それぞれ PC / mobile / iPhone と判定されて用事されることがわかります.
iPhone で絵文字
:
PC と携帯料対応のサイトを作成するうえで,iPhone を携帯として扱ってしまいたい場合もあるでしょう.
その場合に絵文字をどうするかが問題となります.表示させるか表示させないかですが,前述のように jpmobile を request.mobile? => true として扱ってしまうと,絵文字を変換して表示しようとしてしまいます.
しかし Iphone クラス用の絵文字の変換方法がわからないため,そのまま表示してしまいます.
このままでは見栄えが良くないので,表示させないようにする方法と,変換する方法を紹介します.
jpmobile の絵文字変換について
その前に jpmobile の絵文字変換について簡単に紹介しましょう.
jpmobile では絵文字変換を ActionController の around_filter で実現しています.around_filter なのは,
キャリアごとの絵文字コード -> 内部コード -> キャリアごとの絵文字コード
と前後で変換が必要だからです.実際のコードは lib/jpmobile/filter.rb に書かれています.
ここで変換処理は下記のようにキャリアごとの場合分けされることになります.さきほどのは Iphone クラスの場合がないので,何も変換されなかったということです.
Outer クラスの to_external メソッドで絵文字をどの形式に変換するかを指定しています.
iPhone 用絵文字変換テーブルの作成
さて iPhone は絵文字をどう指定すれば表示できるのでしょうか.前回,docomo の携帯電話でサッカーボールの絵文字を
 で指定したように,jpmobile ではビューで絵文字を指定するときに UTF-8 の数値参照を使います.WEB&NETWORK絵文字一覧01によれば,softbank
の携帯電話ではサッカーボールの絵文字は 
で表示されます.また,ke-tai.orgによると,iPhone
の場合は UTF-8 の数値参照ではなく,Unicode の数値参照を指定すれば表示されるようです.
jpmobile の絵文字変換テーブルは lib/emoticon/conversion_table.rb にあります.
上記の  から  への変換を探してみても見つかりません.
jpmobile では Softbank の絵文字は UTF-8 コードで +0x1000 だけずらされているので, ではなく  への変換をテーブルから探します.
すると Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK の中で下記の指定が見つかります.
0xE656=>0xF018,
では実際に console で変換してみましょう.絵文字は Jpmobile::Emoticon::unicodecr_to_external メソッドで変換するので,下記のようになります.
この “\e$G8\017” というのは Softbank 携帯で絵文字を表示するときに使うウェブコードです.
では実際に  が Jpmobile::Emoticon::unicodecr_to_external メソッドでどのように変換されているかを見てみましょう.
まず str.gsub によって数値参照の 16 進数部分がマッチし,その後 scanf メソッドにより数値 unicode = 0xe656 へと変換されます.
変換テーブル Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK からこれは converted = 0xF018 に変換され,次の case 文で when Integer の節が実行されます.
最終的に SOFTBANK_UNICODE_TO_WEBCODE でウェブコードに変換されます.
さて iPhone の場合はここではウェブコードではなく Unicode に変換しなければなりません.
また今回は数値参照で表示したいので,変換テーブルを自作することにします.
とは言っても絵文字自体は Softbank のものを使うので,ここでは Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK を元にして Jpmobile::Emoticon::CONVERSION_TABLE_TO_IPHONE を作成したいと思います.
Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK は絵文字数値参照コードを Softbank 絵文字の Unicode + 0x1000 の数値に変換しています.
これを「Softbank 絵文字の Unicode」の数値参照に変換すればいいので,下記のようになります.
これを RAILS_ROOT/lib/jpmobile/mobile/iphone.rb に追加して実際に試してみます.
これで変換テーブルができました.では次に変換処理に組み込みます.変換テーブルは Jpmobile::Filter::Emoticon::Outer.to_external メソッドで決定されているので,この部分を上書きします.
:
request.mobile のクラスが Iphone であった場合は自作の変換テーブルで変換し,それ以外は元の処理に委譲するようにしました.
ではこれも RAILS_ROOT/lib/jpmobile/mobile/iphone.rb に追加して確認してみましょう.script/server を再起動して FireMobileSimulator で確認します.
画像ではソフトバンク絵文字が表示されています.ソースコードを確認すると確かに  に変換されていることがわかります.
実機で表示させるとこのようになります.
文字コード変換
さてこれでいいようですが,このままでは文字コードが Shift_JIS となってしまっています.jpmobile では request.mobile が Softbank / Vodafone クラスとなる機種以外を Shift_JIS に変換してしまいます.
そこでこの部分を上書きして,Iphone クラスも変換しないようにしてみましょう.変換処理は Jpmobile::Filter::Sjis.apply_incoming? で実行するかどうか判定しているので,ここを書き換えます.
これでようやく iPhone 用の絵文字処理ができました.かなり入り組んでいるのですが,jpmobile がどのようにして変換しているのかが垣間見えたでしょうか.
絵文字を表示させないようにする方法
では最後に絵文字を表示させないようにしてみましょう.絵文字を表示させないようにするには,先程の絵文字変換テーブルで変換先を空文字列にしてしまえば大丈夫です.
これで絵文字は空文字列に変換されるので,表示されなくなります.
絵文字対応のまとめ
今回作成した iPhone 用のファイルは以下のようになります.絵文字は表示させる方のコードです.
少し複雑ですが,それほど長くない行数で iPhone に対応させることができました.
まとめ
今回は iPhone 対応を紹介しましたが,同じようにクラスを追加すれば Android やスマートフォンにも対応可能です.また対応させる上で必要な jpmobile の内部構造も,一部ですが紹介することができました.「もっとこうしたい!」と言う方はぜひ開発に参加してみてはいかがでしょうか.
リンク
- HP
- RDoc Documentation
- GitHub
- Mailing List
- IRC Channel
- #jpmobile@freenode.net
著者について
Rust/OGAWA (@conceal_rs)
300 万人規模の携帯向けメーリングリストサービスを Ruby on Rails で構築・運用している人
jpmobile / termtter のコミッターでもある.
jpmobile + Rails 2.3.x で作る携帯サイト入門