頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


UIAlertViewのメッセージ表示を一行で記述する

値のチェックなんかで、デバイスをMacとつないでる時だとコンソールに出力させたらいいけど、そうじゃなければUIAlertViewを使う時がたまにあるのよ。
単にメッセージを表示させてOK押しておしまい、みたいなの。コードだとこんな感じかな。
{
    UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:nil message:@"Called hoge:" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
    [alertView show];
}
それを毎回書くのが面倒になってさ、カテゴリ作っちゃったよ。ここはやっぱりUIAlertViewのカテゴリってするのが自分的には一番しっくりくるかなってことで。
@implementation UIAlertView (ShowMessage)
+(void)showMessage:(NSString *)text
{
    [[[[UIAlertView alloc] initWithTitle:nil message:text delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease] show];
}
@end
こうしておけばコード内で何かアラートを表示させたい時は
{
    [UIAlertView  showMessage:@“Called hoge:”];
}
みたいに一行ですっきりするじゃない。

alertView出力時

ちなみにこういうカテゴリを入れたファイルは-Prefix.pchで読み込むようにしてクラス内のどこからでも使えるようにしてる。もう最近はいかにラクにするかってのに注力してるなあ。


Xcode 5でユニットテストをテストしてみた

Xcode 5にしてからだったと思うんだけど、新規にプロジェクトを作ると頼んでもいないのになんちゃらテストってファイルみたいなのが一式作られるじゃない?

ユニットテスト関連ファイル

なんだよこれ?うざいなあと思っていたんだけど、一体どんなものか調べてみたら、、、もしかしてこれってすごく便利なのかも?!

Xcodeユニットテスト ガイド
↑これによるとSenTestingKit.frameworkを使ってて、確かにネット上でサンプル拾うとSTAssertNotNilのようにSTで始まるマクロがたくさん記述されてたりする。
Xcode 5だとデフォルトで使うフレームワークはXCTest.frameworkなのでST〜ってのはそれ以前なのかな。

どうも
ロジックユニットテスト
アプリケーションユニットテスト
の二種類があるみたいなんだけど、最初は何がどう違うのかよくわからなかったんだ。
でもDeveloper Centerにあるサンプルコード(電卓のやつね)でようやく納得。

ロジックテストはアプリ内のクラスやメソッドのテストをするのにオブジェクトを自分で作成するsetUpメソッド内で自分でクラスのオブジェクトを作ってやるのよ。こんな感じで。
-(void)setUp 
{
   calculator = [[Calculator alloc] init];
   STAssertNotNil(calculator, @"Cannot create Calculator instance");
}
それに対してアプリケーションユニットテストの場合は下のようにアプリ内が実行された時の参照を得て、それに対してごにょごにょとテストしてるんだよ。
- (void) setUp {
   app_delegate         = [[UIApplication sharedApplication] delegate];
   calc_view_controller = app_delegate.calcViewController;
   calc_view            = calc_view_controller.view;
}
そういうことなのかあ。


あと、テストを実行したらすぐに終わっちゃうので非同期処理の場合はどうするのかな?と思ったんだけど、、、
SenTestCase で非同期処理のテストをする方法 - A Day In The Life
こういう方法があるみたいなので試してみようとしたんだ。MultipeerConnectivity.frameworkで二台のiOSデバイスが接続できるかテストしたかったんだけど、、、Xcodeからテストできるのはデバイス一台だけらしく、二台目の起動はしてくれなかったよ。

エラーメッセージ

↑一台目を待たせている間に二台目を起動しようとしたら断られた、の図。 Build & RunはXcodeから複数台でもやってくれるから、そんな感じでテストもやってくれるものかと思ってたんだけどね。


アプリの順位が上がった時だけ通知してくれるアプリを作ってみた

他の人はどうだか知らないけど、俺は自分のアプリがどのくらいダウンロードされてるか気になるんだよ。特に順位が上がっているともしかしてカテゴリ一位になるのか?!なんて頻繁にiPhoneでAppStoreを見に行っちゃうんだ。いや、ホント時間の無駄だよね。そのくせ順位がだだ下がりの時はあまり見たくない、というまあ素直な俺なんだよ。

それでこの時間の無駄と精神的苦痛の解消のため、iPhoneが数時間ごとに俺アプリの順位を調べて前回より上がっていれば通知してくれる俺専用アプリを作ったんだ。ここにもちょっと書いたけど → 頭と尻尾はくれてやる! / iPhoneで一定時間ごとになにかを処理させるには?

処理の流れはこんな感じ。

1)Background fetchでテキトウにiPhoneが起動
2)一定時間経過していればAppStoreへ順位を調べに行く(Search API
3)順位が前回調べた時より上昇している場合のみ通知する(UILocalNotification)

順位通知アプリのスクショ

↑アプリ内では順位の経過を単に表示させてるだけだけど、これをApp AnnieのようなグラフにでもすればAppStoreでリリースできる体裁は整う気がしないでもないけど、、、まあダウンロードされないだろうな。

ともかくこれのおかげで最近はいちいちAppStoreへ行くことがなくなったよ。


iPhoneで一定時間ごとになにかを処理させるには?

iOSアプリで一定時間ごとになにか処理をさせたい場合はどのようにすればいいのかなあ?と思って見つけたページ。
【iPhoneアプリ】バックグラウンドで定期実行 | RS-Flip-Flop
↑この記事を見て、なるほどVoice over IPアプリのふりをしてかあ、、、記事内にあるようにちゃんとその機能を実装しておかないとリジェクトされるんだろうけど、まあ考えてるのは俺専用アプリだしいいやってことでテストしてみたんだよね。

まあテストといってもapplicationDidEnterBackground:内に下のような記述を追加してちゃんと処理されるか観察していたんだ。
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[UIApplication sharedApplication] setKeepAliveTimeout:600.0 handler:^{[self method];}];
}
最初はそれらしく method がコールされるんだけど、、、数時間するとどういうわけかぷっつり起動しなくなってしまうんだよ。
それはまずいなあってことで他の方法をテストしてみたんだけど、それがiOS 7で導入されたBackground Fetch。

Objective-C - Background Fetch を試してみた - Qiita [キータ]

↑とても参考になったページ。あまりにうまくまとまっているから何も書く気がしないやってくらいだよ。

このBackground Fetchでやると完全に(例えば)1時間ごとになにか処理する、というほどの精度はないんだけど、用途によっては使えなくもない。何より安定して動いてくれるしね。


Background Fetchを使ったアプリのスクショ

↑コレはこのBackground Fetchを使った俺専用アプリのスクショ。
起動のタイミングは、UIApplicationBackgroundFetchIntervalMinimumでインターバルを最小にしてる。
起動したらその時間をメモしといて前回より1時間以上経過していればApp StoreのサーバにSearch APIを使って俺アプリの順位を調べて記録してる(そうなんだよ、サーバー問い合わせるために定期実行して欲しかったのよ)。
時間を見ると妙に間隔が空いてるところもあるけど、まあそれなりに動いてくれてるみたい。







Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.