2008年12月27日土曜日

iPhoneでMap Viewを使いたいので、ライブラリを探してみました

  • iPhone Google Maps Component
  • route-me
  • TouchMap
  • 個人的にはroute-meがおすすめ、ただしMicrosoft Virtual Earthを使うことになる
  • ストリートビューが欲しい、またはどうしてもGoogle Mapで実装したいという人はAppleがCocoa Touchに組み込んでくれるのを期待しつつ待つしかない

iPhoneで開発をしている人なら、誰しも一度はこう思うでしょう。
「標準のGoogle Mapアプリみたいに、地図を使ったアプリが作りたい」と!
GPS・加速度センサー・タッチ操作に強力な通信機能、おまけに3D描画もできると、
こんなにすてきな機能と地図がくみ合わさったら、その可能性は無限大に違いありません。

が。しかし、なんということでしょう。
皆様ご存知の通り、Cocoa Touch Frameworkに地図機能は存在しないのです!
ライバルのAndroidにはあんなにすてきな地図機能があって、自由に使えるというのに!

さてさて前置きが長くなってしまいましたが、要するに、

「iPhoneでMap Viewが使いたいんだけどどうすりゃいいの」

ということです。
調べてみたところ、以下の3つのオープンソースライブラリが見つかりました。

○iPhone Google Maps Component
http://code.google.com/p/iphone-google-maps-component/
その名の通り、Google Mapを利用したMap Viewライブラリです。
実装にはiPhoneのUIWebViewを利用しており、JavaScriptを用いてGoogle Mapにアクセスし、
描画を行っているようです。
画面上に描画点(プロットとか画像とか)を自由に配置することができます。

○route-me
http://code.google.com/p/route-me/
こちらはObjective-Cネイティブ実装のMap Viewライブラリです。
ネイティブ実装であるため、きわめて軽快で高速な動作が特徴です。
ただし地図の提供元がOpenStreetMapか、Microsoft Virtual Earthに限られてしまいます。

○TouchMap
http://toxicsoftware.com/touchmap/
全く未知数です。
Objective-CまたはC言語による実装で、
地図の提供元がMicrosoft Virtual Earthであるということ以外何もわかりません。

いずれもGoogle Map StreetViewには対応していません。

さて、この中のどれを選ぼうか・・・というところですが
まずiPhone Google Maps Componentは真っ先に除外されます。
JavaScriptで実装されているため実機では重すぎて使い物になりません。唯一のGoogle Mapsを用いた実装だけに非常に残念です。
残る二つからroute-meをとるか、それともTouchMapをとるか悩みましたが、
TouchMapのほうがドキュメントが少なく、また開発頻度が悪い(10月から一度も更新されていない)ため、
現在最も勢いのありそうなroute-meを今回採用することにしました。


次回はroute-meのページに用意されているインストールの手引きを見ながら、
実際に自分のアプリの中で地図を動かしてみようと思います。
http://code.google.com/p/route-me/wiki/EmbeddingGuidev2

2008年12月25日木曜日

CS193P Cocoa Programming - AssignmentPresence3まで完了


最近ご無沙汰気味でしたが、
なんとかPresenceアプリ作成の宿題3まで完了させることができました。

リロードボタンと投稿ボタンがつきました。



詳細画面を見るとこんな感じです。ちょっと寂しい。




投稿ボタンを押すとこうなります。
UITextFieldではなくてUITextViewを使った方がよかった気がします。まぁいいや。


ソースコードなどは以下に公開しております。
http://github.com/akisute/akisute_cs193p/tree/master


残るはPresence4だけなのですが、Presence4の内容は正直それほど難しくない(TabBarを使うぐらい)ので、
ここらですっ飛ばして今興味があるroute-meという地図ライブラリの解析でもやってみようと思います。

2008年12月21日日曜日

Cocoa(iPhone)で、日本語を含むURLを開く方法

  • 基本的にはCore FoundationのC関数を利用する
    CFURLCreateStringByAddingPercentEscapes()
  • ただし、一部問題のあるケースがある
    URL中に&を含む場合などは正しく作れないので別の方法が必要

プログラマをやっていると、だんだんと日本語が嫌いになってきます。
いや、嫌いというのはおかしいのですが、とにかく英語以外の言語はトラブルが多いです。
コンピューターというのはつくづく英語を処理するためだけに作られているのだと思います。
(だからこそ、プログラムの「国際化」で飯を食える人がいる訳ですけど!)

すみません、前置きが愚痴っぽくなってしまいました。
iPhoneプログラミングにおいてももちろん、日本語を使う際に罠があります。
たとえばNSURLRequestなどがそうです。
日本語の含まれるURLを開こうとすると、うまく解釈してくれないんです。
(といいますか日本語が含まれるURLはURLエンコードしなくちゃいけないんです。・・・当たり前ですね)

例えばこんな感じです:
http://s3.amazonaws.com/twitter_production/profile_images/65140989/るーみゃ_normal.jpeg


自分の画像だけ出ないぞ!

そこでURLエンコーディングを行う関数を探してみたところ、ありました。
Cocoaで日本語のGETを飛ばそう!

早速真似してやってみました。
CFURLCreateStringByAddingPercentEscapes()関数を使うのがポイントらしいです。
            NSString *originalUrl = [userDict objectForKey:@"profile_image_url"];
           NSString *encodedUrl = (NSString *) CFURLCreateStringByAddingPercentEscapes
           (NULL, (CFStringRef) originalUrl, NULL, NULL, kCFStringEncodingUTF8);
           person.profile_image_url = encodedUrl;

たったのこれだけでうまくいきました!



ところが、有頂天になってTwitter上で騒いでたら、
@psychsさんから突っ込みが。
JavaScriptでいうencodeURI相当なんで、
日本を適当にエスケープしたいときにはいいんだけど、
たとえばパラメタに「&」を入れたい場合とかは、
ちゃんとencodeURIComponent 相当のやつを使って組み立てなきゃだめだよ

なんと具体的なアドバイス!(ありがとうございます!)ちょっと調べてみました。
javascript: escape(), encodeURI(), encodeURIComponent() 比較

細かいところはわかりませんが、とにかく一部の文字がエンコーディングされないみたいなのです。
深刻なのは?とか=とかでしょうか。気をつけないとトラブルに巻き込まれそうですね。

ちなみにiPhoneでencodeURIComponent相当のエンコーディングを行うためにはどうすればよいのかですが、
リファレンスを引いてみても特にそれらしきものは見当たりませんでした。
ひょっとしたら自分でやるしかないかもしれません。

■2008/12/29 22:00追記
Twitter上で、@norio_nomuraさんにencodeURIComponent相当のエンコードを行う方法を教えていただきました!ありがとうございました!
http://twitter.com/norio_nomura/status/1083641557
CFURLCreateStringByAddingPercentEscapes(NULL, string, NULL, CFSTR (";,/?:@&=+$#"), kCFStringEncodingUTF8);

最大のポイントは、第4引数のCFSTRです。ここで指定した文字列はエンコードされずにそのまま残るようです。
第4引数をNULLのまま使うと標準のencodeURL相当になり、
この例のように指定すると、encodeURLComponent相当のエンコードが可能になります!