2013.09.22 · 技術と道具

iOS7で可能になったAppのバックグラウンド更新を調べた

iOS7では、設定アプリに一般>Appのバックグラウンド更新というメニューが追加されています。

いろいろネットで検索してみると、「バッテリー浪費するかもしれないからOFFにした方が良い」というTipsブログのオンパレードだったりするのですが、エンジニア的にはこれってどういう機能で、どうすれば使えるの?という方が気になります。

これは、Xcode5(iOS SDK7)上でプロジェクトの設定を開き、CapabilitiesタブのBackground ModesをONにして、さらに、Modesの中からBackground fetchかRemote notificationsのいずれかをONにすると、Appのバックグラウンド更新にアプリが表示されるようになります。

iOS6までのマルチタスク

Background fetchとRemote notificationsで何が出来るかの説明の前に、iOS6までのマルチタスクについておさらいをしておきましょう。

iOS6では、アプリがバックグラウンドになった際の処理は、一部の機能を持つアプリに限定して許可されていました。それ以外のアプリはバックグラウンドになった後は10分間だけ処理が可能で、その後はサスペンドになってしまいます。
そのため、一般のアプリでは、サーバとのデータ同期処理等をバックグラウンドで自動的に行ったり、通知が来た際にバックグラウンドで何か処理を行うといったことが出来ません。

Background fetchで何が出来るか?

Background fetchはiOS7で追加された機能で、アプリがバックグラウンドになった際に、一定の間隔でデータの取得処理を行うものです。

「一定の間隔」といっても、指定できるのは「OSでサポートされる最小の間隔(UIApplicationBackgroundFetchIntervalMinimum定数)」か、「バックグラウンド更新をしない(UIApplicationBackgroundFetchIntervalNever定数)」のいずれかしかないようです。
データ取得にログインが必要なら、ログインしている場合はUIApplicationBackgroundFetchIntervalMinimum、ログアウトした場合はUIApplicationBackgroundFetchIntervalNeverを指定するといった感じにするのが良いのではないでしょうか。

OBJECTIVEC
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];

実際の取得処理は、performFetchWithCompletionHandlerです。

OBJECTIVEC
- (void) application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    //コンテンツの取得処理

    if (success) {
        //処理に成功した場合
        if (hasNewData) {
            completionHandler(UIBackgroundFetchResultNewData);
        } else {
            completionHandler(UIBackgroundFetchResultNoData);
        }
    } else {
        completionHandler(UIBackgroundFetchResultFailed);
    }
}

Remote notificationsで何が出来るか?

Remote notificationsもiOS7で追加された機能で、サーバからのPush通知をトリガーとして、バックグラウンドでデータの取得処理を行うものです。
サーバ側でのデータ更新があった際にPush通知が出来るのであれば、Remote notificationsを使った方がバッテリーの節約が出来そうです。

UIApplicationのdidReceiveRemoteNotificationメソッドに、fetchCompletionHandler引数が付いたものがあるので、それを使ってPush通知時のバックグラウンド更新を行います。

OBJECTIVEC
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    //コンテンツの取得処理

    if (success) {
        //処理に成功した場合
        if (hasNewData) {
            completionHandler(UIBackgroundFetchResultNewData);
        } else {
            completionHandler(UIBackgroundFetchResultNoData);
        }
    } else {
        completionHandler(UIBackgroundFetchResultFailed);
    }
}

■

これは開発者が上手く使ってあげれば、便利な機能だと思います。

<2013/10/18追記>
Remote Notificationでのバックグラウンド更新を行う場合、通知のペイロードにcontent-available=1という項目が必要です。詳細は、iOSのPUSH通知(APNs)の種類について、ざっくり。をどうぞ。

2013/09/22 08:24
← PhoneGap + jQuery Mobile + iOS…
Nikon D5200と行った福岡撮影行(鉄道編) →
井上 研一
経済産業省推進資格ITコーディネータとして中小企業のDX・AI活用の現場で伴走支援を行う。「ITCプロセスガイドライン4.0」および「中小企業向けAI活用ガイド」執筆メンバー。著書・講演多数。ITエンジニアとして25年以上の実務経験。AI導入の実務に10年以上携わる。自ら開発したAIサービス「Gen2Go」が北九州発!新商品創出事業の認定を受ける。2026年4月より北九州市立大学大学院マネジメント研究科の学生としての顔も持つ。

本サイトおよびブログに掲載している内容は、特に明記のない限り、井上研一個人の見解に基づくものです。所属・関与する組織、団体、企業、研究会等の公式見解を示すものではありません。