読者です 読者をやめる 読者になる 読者になる

iOS7の「Appのバックグラウンド更新」を無効化されたら困る場合はユーザーへ伝えよう

もともとiPhoneではバックグラウンドでの動作が非常に制限されていたこともあり、バックグラウンドで動作し続けるアプリというのは裏で動き続ける必要性、必然性があるものがほとんどです。Appのバックグラウンド更新をオフにすると、それらのアプリは問答無用でバックグラウンドでの動作が制限されます。オフにするのならその意味をちゃんと考えてからオフにしてください。

私のアプリでは「iOS7になったらバックグラウンドでログが記録出来なくなった!」という不具合報告をいくつも頂きましたが、その全てがこの「Appのバックグラウンド更新」が原因でした。
安易にオフにしないようお願いします。m(_ _)m

iOS7の「Appのバックグラウンド更新」をオフにしてはいけない | dendrocopos開発室

これは言いたいことはわかるんだけど、まずユーザーの意思が第一で、デベロッパーはバックグラウンド更新への対応のために新APIが追加されてるのをそれを使うべきだと思う。

バックグラウンドでの位置情報サービスを要求するアプリケーションであっても、ユーザによって明示的にバックグラウンド機能を無効にすることができます。
ユーザが「設定(Settings)」アプリケーションで「Background App Refresh」を(すべてのアプリケーションに対してグルーバルに、または特定のアプリケーションに対してのみ)無効にすると、アプリケーションではバックグラウンドで位置情報サービスを使用できなくなります。
アプリケーションがバックグラウンドで位置情報の更新を処理できるかどうかは、UIApplicationクラスのbackgroundRefreshStatusプロパティの値をチェックすることで決定できます。

位置情報とマッププログラミングガイド https://developer.apple.com/jp/devcenter/ios/library/documentation/LocationAwarenessPG.pdf

コードにするとこう、設定変更を監視する。

// iOS 7.0 以上の[Appのバックグラウンド更新]設定の変更への対応
if([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] == NSOrderedDescending){
  [[NSNotificationCenter defaultCenter] addObserverForName:@"UIApplicationBackgroundRefreshStatusDidChangeNotification"
                                                    object:nil
                                                     queue:[NSOperationQueue mainQueue]
                                                usingBlock:^(NSNotification *notification) {
                                                  // 設定を変更して再度アプリを復帰した時に呼ばれる
                                                  if([UIApplication sharedApplication].backgroundRefreshStatus == UIBackgroundRefreshStatusDenied){
                                                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"[Appのバックグラウンド更新]設定をオフにしているためバックグラウンドでログを記録できません。"
                                                                                                    message:@"この機能を再び有効にするには[設定]→[一般]→[Appのバックグラウンド更新]からこのアプリの更新を許可してください。"
                                                                                                   delegate:self
                                                                                          cancelButtonTitle:@"閉じる"
                                                                                          otherButtonTitles:nil];
                                                    [alert show];
                                                  }
                                                }];
}

「有効になってない時は警告する」っていう仕様にしたいところだけどiOSの「機能制限」でバックグラウンド更新を許可されていない端末もあるので「無効にされたら警告」ぐらいがいいと思う。まあ制限された端末もステータスで判別できるので専用のメッセージ出すとか、上記のだと変更通知時にしか動作しないので、設定画面では毎回チェックするとかご自分のアプリにあわせて工夫してください。

ちなみに最近バッテリーの持ちが悪くなってきたと相談された時の平均的なアップル信者の回答は「今年出た端末に乗り換える理由があって羨しい」です。