iPhone
iPhone 用アプリ「ExifSafe」について
ソースコード: GitHub - exif
また、このコードを実際に使って次のような iPhone 向けアプリを試作してみました。
「ExifSafe」という名前をつけています。
次の場所で公開しています。興味のある方はお試し下さい。
※「写真.jpg」のような識別性に乏しいシステム既定の添付名の不便さを補うもの
iTunes App Store -ExifSafeソースコード: GitHub - ExifSafe
2018年6月追記:諸般の事情により App Store 上の本アプリの更新は今後当面見送らせて頂きます。本アプリをご利用下さった皆様に謹んで御礼申し上げます。
(tanabe)
ソーシャル携帯電波マップを作ろう
先週出張で東京に来ました。いつものように東北新幹線です。
道中2時間半いつも特に何をすると決めている訳ではなく、まあ寝るか、本を読むか、iPhoneを片手にメールやサイトチェックをするか、うーん、大体は寝ているんじゃないでしょうか私。眠いもの。
ただ、今回いつもとは違いめずらしく眠気がなかったので、おもむろにMacBook Airを開いてcodingなんぞやろうかという気になりました。しかしそれがいけなかった。まだ購入してから間もない状態だったので、環境が全く整ってない。それどころか書こうとしていたソースコードパッケージすら入れてないときたもんだ。…いや、まあ、でもこういうときに備えてMobileMeのストレージにスナップショットを置いてあったりしただろ落ち着け俺、とやおらPocketWifiを取り出してダウンロードを始めた。が、落ちて来ない。
そうだった。東京から宇都宮〜那須塩原あたりまでのだだっ広い関東平野goes onならいざ知らず、上り列車乗り込んですぐの盛岡あたりでは移動の途中で圏外になることも多く、なかなか使い物にならないのである。市街地はそこそこにしてすぐに田園と山林風景のど真ん中を行くことになるわけだから、ビジネス用途の強いイーモバイルの電波は届かなくても仕方が無いのだ。こいつはぎゃふんだ。
というわけで、行きの電車内で大いに苦しめられたこの電波状況、キャリアのサービスマップだけでは分からない、「ほんとにほんとのところどうなのよ?」というあたりを調べてみようと思った。言ってみればユーザ実測によるリアルサービスマップ。ソーシャル時代の今ならこれをみんなで寄せ集めて日本全国くまなく調査することだって夢じゃない。そうそう、時代はパソーシャル…、と、そんなことを妄想しながらその後ほどなく私がふて寝に入ったのは言うまでもない。
概要はこうだ。新幹線で移動する間中、ずっとGPSで現在位置を把握する。そして並行してPINGを打ち続け、GPSでの位置・PING送信・応答これら3つのイベントを時間軸に沿って記録する。後でこれを地図上にプロットしてみようというわけだ。
手元にあるのはiPhoneとMacBook Air。iPhoneにはGPSがついているので問題ない。PINGの実装はちょっと悩んだが、Cocoaのサンプルコードにちょうど"SimplePing"というそのものズバリなものがあるのを見つけた。Mac用となってはいるが、iOS用にも移植できるんじゃないかと見立て、これを持って来てみた。
http://developer.apple.com/library/mac/#samplecode/SimplePing/Listings/SimplePing_m.html
SimplePing: SimplePing.m
幸いADC(Apple Developer Connection)に登録しているので、iPhoneにアプリケーションを転送して実機でアプリを動かすことはできる。ここまで調べたところで出張が終わり、さあ帰りの新幹線の便となった。
帰りの新幹線。シートに座ってMacBook Airを開いて作業を開始。列車も東京駅を出発。途中小山駅を過ぎたあたりで空腹が勝りすぎて弁当を食さずにはいられなくなるなどアクシデントに遭いつつも、白石蔵王を通り過ぎ仙台駅にさしかかったあたりまでで一通りのものが出来た。
やった内容は大まかにこう。
- まず、Xcode上でFile > New > New Projectのメニューを選び、iOS Applicationから新規アプリケーションを作成する。"Navigation-based"でも、"Tab bar"でも何でも良い。名前も何でも良い。
- SimplePingから、SimplePing.{h,m}ファイルを持ってくる。また、SimplePingがPING応答の際にコールバックするdelegateクラスがmain.m中にあるので、それを持ってくる。
- 上記のdelegateクラスを今回新規作成したアプリケーションにおけるNSApplicationのdelegateクラスに対するカテゴリ(Mix-in)として実装に追加する。
- アプリケーション起動時に呼び出されるコールバックメソッド"application:didFinishLaunchingWithOptions:"において、GPSおよびPING送信を開始するためのコードを追加。
- さらに、GPS出力およびPING送受信の結果を記録するデバッグログを追加。
- ↑の情報は、作業工程圧縮のためiPhone上でのデータ書き込み機能を実装せず、とりあえずXcodeデバッガの出力に任せる。iPhoneはMacにUSB接続したまま動かす。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. // Add the navigation controller's view to the window and display. self.window.rootViewController = self.navigationController; [self.window makeKeyAndVisible]; // ↑ここまでテンプレート // ここからGPS準備 _locationManager = [[CLLocationManager alloc] init]; _locationManager.delegate = self; [_locationManager startUpdatingLocation]; // ここからPING準備 self.pinger = [SimplePing simplePingWithHostName:@"www.klab.jp"]; self.pinger.delegate = self; [self.pinger start]; return YES; }
ざっとこのくらい。これで一応デバッグログにPING送受信とGPSの結果がタイムスタンプとともに吐き出されるので、最低限のデータが取れる。本来ならMapKitと組み合わせてリアルタイムに地図表示まで持っていきたかったところだが、敢えなく時間切れ。
さて仙台を抜け、多くの客が降りだいぶ客席にも余裕ができた頃、最初の試行を開始。しかしそのときちょうどトンネルに入ったらしく、あっけなく問題が発生。上記コード例から分かるように"www.klab.jp"へのPING送信のため名前解決をしているのだが、起動時にしくじるとリトライをしない実装になっているため、トンネルを抜けるまで始められないというバグにぶちあたった。
そうなのだ。仙台から北はまさに行きで悩まされた難受信地域。一足遅かったか…と一瞬天を仰ぐも、気をとりなおしてトンネルを抜けてアンテナが立つと共にリトライ。その後も途中何度も圏外になり、細かいデバッグや調整を繰り返しながら、何とかデータを取ることができた。
データを時間軸で残すようにしたのは大正解だった。作業時間の圧縮のため、デバッグログNSLog()関数での出力にせざるを得なかったが、デフォルトでタイムスタンプ込みの出力をしてくれるため大変助かった。
何しろ、PINGの送信時点と応答受信時点のタイムスタンプを計算すればRound Trip Timeが計れるが、そのくらいアプリケーション内で計算できれば本当はよいものの、デバッグログに逃がすことでその計算も後回しにすることができたのだから。お尻の時間が決まっている場合は、「イカにして必要な作業に集中して手間と時間を投入するか」が重要になってくるということじゃなイカ?
さて、この次にデータをいよいよ地図上に表示する作業に移るわけだが、ここまできてはたと気がついた。Macでネットワークがつながらず往生したのはPocketWifiでだったが、今回iPhoneはそのまま3G回線、すなわちソフトバンク経由でPING送っていたということに…。
まあ、そんなこともありますよね。えへ。
(こうら ひろのぶ)