koogawa blog

iOS、Android、foursquareに関する話題

バックグラウンドで動くアプリが終了されたタイミングでアラートを出す

僕の来た道」や「Moves」のように、バックグラウンドから意図的にアプリを終了されると行動記録が取れなくなり、非常に困るアプリがありますね(iOS 7以上での話)。

そんな中、「AutoDiary」というアプリが面白いことをやっていました。

f:id:koogawa:20140121001634j:plain

バックグラウンドからアプリを終了すると、上のように通知で知らせてくれるのです。これは上手いやり方だな、と思いました。

AutoDiary -PreVersion for iOS6-

AutoDiary -PreVersion for iOS6-

  • Tama
  • ライフスタイル
  • 無料

というわけで、さっそく実装方法を調査してみることに。

やり方

とりあえず思いついたのが、Local Notificationを使う方法です。

アプリが終了されたタイミングでLocal Notificationを発動させる

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    NSLog(@"Terminated");

    UILocalNotification *notification = [[UILocalNotification alloc] init];
    if (notification)
    {
        notification.timeZone = [NSTimeZone defaultTimeZone];
        notification.repeatInterval = 0;
        notification.alertBody = @"アプリを終了したから正常にログが取れないからね!";
        notification.alertAction = @"再起動";
        notification.soundName = UILocalNotificationDefaultSoundName;
        [[UIApplication sharedApplication] scheduleLocalNotification:notification];
    }
}

ただし、このままだと applicationWillTerminate は呼ばれません。

原因を調べているうちにStack OverflowのサイトでこんなQ&Aを発見。

どうやら、バックグラウンドで何か動いていないと applicationWillTerminate は呼ばれないようです。

とりあえず、バックグラウンドで位置情報を取得し続けた状態でもう一度試してみることに。

バックグラウンドモード追加

バックグラウンド状態でも継続して位置情報を取得し続けるために、Info.plist の Required background modesApp registers for location updates を追加します。

f:id:koogawa:20140121005525p:plain

これだけでは、まだ applicationWillTerminate は呼ばれません。実際に位置情報を取得し続けないといけないようです。

位置情報を取得し続ける

    if ([CLLocationManager locationServicesEnabled])
    {
        _manager = [[CLLocationManager alloc] init];
        _manager.delegate = self;

        [_manager startUpdatingLocation];
    }

ここまで実装したら一度アプリを起動し、ホームボタンを押してバックグラウンド状態にします。そして、ホームボタンをダブルタップ。

f:id:koogawa:20140121002439j:plain

App Swicherからアプリを上にフリックしてアプリを終了させると。。。

f:id:koogawa:20140121001827j:plain

ちゃんと通知されました!

※なんか間違ったこと書いていたら訂正お願いしますm(_ _)m

まとめ

これでアプリが意図的にバックグラウンドから終了されたタイミングで、ユーザに何かしらのアラートを出せるようになりました。

iOS 7にアップデートしたらアプリが何も記録しなくなった★1」的なレビューが少しでも減ることを祈っております。

ちなみに、ソースコードこちらにアップしておきました。