2010-07-28

駅ベル - 1.1.0 バージョンアップのポイントをまとめました


  • 駅までの距離に従い、精度を上げるようにした
    • アラームが正しく動作する率がアップ
    • 目的地まで遠い場合にはバッテリーの持ちアップ
  • iPodで音楽再生中にも、ちゃんとアラームが鳴るように
  • バックグラウンドでも、正しく音が鳴るように
  • バックグラウンドでも、バイブレーションが動作するように
  • 設定画面を追加
    • アラームの音を変更可能に(4種類内蔵)
    • バイブレーションを選択可能に(iPhoneのみ)
    • アラーム開始距離を変えられるように(右図)
  • iPhone 4 Retina Display対応(持ってませんが)

実は今回の一番の見所は、内部のロケーションマネージャの使い方を1から見直して、完全に新しい実装で書き直しました。本当に最小限の必要としている部分でしかロケーションマネージャーを使わないように細かいチューニングを行ったので、バッテリーの持ちは前のバージョンよりもかなりよくなっています。使っているときはステータスバーのロケーションインジケータが出るので、画面ごとに出たり消えたるすることで確認できると思います。

ロケーションマネージャについては、iOS4のマルチタスキングの売りの一つだけに、バッテリーの持ちとの新たな戦いの部分、別エントリーで書きます。

駅ベルのバージョンアップでリジェクト食らいました。その顛末。

今回の駅ベルのバージョンアップは、バックグラウンドで音が鳴らないという部分の対応。UILocalNotificationに任せておけばいいかなと思ってたんですが、ちゃんと音が鳴って欲しいという要望が強く、対応することに。

長いWaiting for reviewの期間を過ごして、なんといきなりリジェクト。その理由がこれ。
We've completed the review of your application; however, because no audible content is played when the application is in the background, we cannot post this version to the App Store. We have included additional details below to help explain the issue. We hope you’ll consider revising and resubmitting your application.
iOS4向けのマルチタスキング対応アプリケーションの一つの機能、バックグラウンドでの音声再生機能を使いたいためにフラグを付けたんだけど、それが裏目になった模様。おまえのアプリケーションは音を出して内じゃないか、と。ふーむ。

そりゃぁ、カリフォルニアではまだ鳴らないっつーの(笑)。どうもアプリケーションの動作を正しく理解してもらえてない模様。普段なら慌てるところですが、どうせ自分のアプリケーション、落ち着いて対応してみました。一度Rejectedになっちゃっているので、バイナリを再度アップロードしないでも再審査してくれるか不明だったので、ちゃんと行くかどうかのテストケースになります。

いろいろ騒ぐ前に、まずはちゃんとレビューチームとコミュニケーションを開始することが一番です、と言うアドバイスももらったので、まずはメール。

Dear review team,
My application uses audio to notify user as alarm sound. My application has to play sound in background mode, and I have no idea without adding "audio" flag. 
The Apple engineer I met at the WWDC Lab said, only way to play sound is to add "audio" flag in UIBackgroundModes. If still you reject my app, please tell another way to play alarm sound in background. I think that's not fair.
- My app plays audio when the device close to the station.
- Playing audio in background needs "audio" flag in UIBackgroundModes.
Other audio application can be paused. My application is also paused until it reaches to destination, isn't it?
Please re-think about this.
Yosuke Suzuki
で、その晩はMOSA entranceがあったので、その場でリジェクトくらったーとネタにしてたりしていたんですが、裏ではことが進んでおり、今朝になってメールが届いてました。

Thank you for you email and clarification.  We are proceeding with the review and will update you with further status as soon as we are able.
Thank you for your continued patience.
短い。あまりに短いが、そしてアメリカ人、決してわびの言葉はないが、ちゃんとスムーズに対応してくれました。
無事にリリース。

教訓。リジェクトされても慌てず騒がず、ちゃんとレビューチームとお話しはしましょう。返事もくれます。他の「Contact us」系のメールと違ってスムーズです。


2010-07-08

CoreDataと再度向き合うことを決定。その前に前回の反省。

昨年からやってるランブリンのデータ部分、当初CoreDataを使っていたんだけど、どうにも使い勝手も悪く感じて、とどめはマイグレーションではまってバージョンアップでトラブル。これでもう、次のバージョンは自分で作ったCoreDataぐらいの互換レイヤーに切り替えよう、というのが今年の2月。

ある程度の時間をかけてMoreDataと言うモノを作り上げて、ランブリン 2.0のコアに使ってみたんだけど、結論から言うとあまり芳しくない状況。特にメモリ効率が極端に悪くなってしまったのが大きな誤算。SQLの使い方にはある程度自身があったんだけど、スレッド・セイフティの確保やフォルトの仕組みなんかを入れていくと速度も芳しくなく、使い勝手やマイグレーションの仕組みは直接的でよかったんだけど、全体的にいわゆる失敗と判断せざるを得なくなってしまった。

メモリ周りはやっぱり難しくて、要はキャッシュの話。何をいつ忘れるのか、これを正しく実装するのが至難の業。iOS4にはNSCacheというクラスが導入されているのも、キャッシュの難しさを表している一端と言えよう。

と言う状況で挑んだ今年のWWDC。事前に去年のビデオでCoreDataを勉強し、ドキュメントももう一度読みこんで、果たして自分はCoreDataの何を間違えていたのか、そういう視点でいろいろと検証していった。結論として


  • CoreDataをいわゆるデータベースととらえていてはダメ。単なるデータを保存する場所ではなく、データが生き続ける環境を提供してくれる環境であって、データをそこから取り出してしまっては、メリットの大半を消すことになる。
  • 同じ理由で、CoreDataを簡単なDBMに見えるようなラッパークラス経由で使ってはダメ。ちゃんとコンテクストを意識して、正しく使わないと意味がない。中途半端なSQLの知識が邪魔をしたのは否めない。
  • マイグレーションは後々絶対はまる場所なので、最初から経験を積んでおくべき。ライトウェイトだろうとなんだろうと、アプリを出した後は実際にデータがたまってしまった状況でテストも出来ないので、かならず各バージョンのデータファイルを保存しておくべき。後から手に入れるのはとても大変。
  • スレッドは最小限に。でも一つは使う。なのでNSManagedObjectIDは登場する。
こんな感じだと思う。もう一度CoreDataに手を出す前にまとめておきたかった。数ヶ月後に何を思うか。

2010-07-07

2010-07-06

言語設定を変えるとバッググラウンドで走っているアプリは殺される

iOS4になって、アプリを開いている最中に環境設定も開けるようになったわけで、ドキュメントにもそれに備えろよ、と言うことは書いてありますが、じゃあ根本的な設定が変わったらどうするの?と。その最たるモノが言語設定。途中で変わると画面から何から作り直さなくてはいけないので、どうなるかと試してみた。
まあ、当たり前と言えば当たり前だが、アプリは黙って殺されます。初期化にし直しましょうと言うことでしょうか。

NSStringのフォーマット文字列生成で位置指定が出来る!

NSStringのフォーマット文字列生成で、 %n$@ というのが使える! (nは数字)

これまでは、必ず

[NSString stringWithFormat:@"Hello %@, (%@)", param1, param2];

のように順番に使われるしかなかったんですが、


[NSString stringWithFormat:@"Hello %2$@, (%1$@)", param1, param2];

のようにすれば、コード中の順番に関係なく文字を埋め込めると言うことです。
知らなかったよ、早速試してみよう。


※ 数字は1から始まるので注意。

ネタ元 : WWDC 2009 Session 106 - Building Localized Mac and iPhone Applications