WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

iOS 7のバックグラウンド処理 〜 Background Fetch

今回のエンジニアブログ担当の山下です。
昨年のWWDCでiOS 7が発表された際、

 Multitasking for all apps with great battery life

と説明があったように、iOS 7ではマルチタスク周辺のAPIが強化されています。
アプリケーションがバックグラウンドで動き続けるということは当然バッテリ消費も早くなります。
そのためバックグラウンドでの動作は必要最低限に抑える必要があります。
iOS 6までは音楽再生やナビゲーションなど、一部機能のみバックグラウンド動作が許可されていましたが、
iOS 7でこの制約が若干緩和された形になります。
新しく許可されたバックグラウンド処理の一つとして、今回はBackground Fetchをご紹介します。

Background Fetchとは

Background Fetchは、必要なデータをバックグラウンドで事前にダウンロードさせるための機能です。
これによりアプリを起動した後、データを読み込むための待ち時間をなくすことが出来ます。

実装

早速試してみましょう。
Xcodeを開き、適当にプロジェクトを作成した後、プロジェクトの設定よりBackground fetchを有効にします。

Background fetchの有効化

次にフェッチする間隔を定めます。
フェッチする最小間隔はUIApplicationの-setMinimumBackgroundFetchInterval:で設定出来ます。
-application:didFinishLaunchingWithOptions:へ以下の記述を追加します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
{  
    [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];  
    return YES;  
}  

デフォルト値はUIApplicationBackgroundFetchIntervalNever(一切フェッチしない)ですので、間隔を設定するまでフェッチは行われません。今回設定しているUIApplicationBackgroundFetchIntervalMinimumは可能な限り短い間隔でフェッチを行います。実際は作るアプリに応じて適切な間隔を秒単位で指定して下さい。また定めているのは最小間隔であり、実際にフェッチするタイミングはiOSが決めます。

最後に実際のフェッチ処理を書いていきます。
UIApplicationに-application:performFetchWithCompletionHandler:を追加します。

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler  
{  
    NSLog(@"fetch");  
    completionHandler(UIBackgroundFetchResultNewData);  
}  

completionHandlerは、処理が完了した際にその結果をiOSへ通知するためのものです。
実際にダウンロード処理を書くときは、結果に応じて次の3つの中から選択し、引数として渡します。

typedef NS_ENUM(NSUInteger, UIBackgroundFetchResult) {  
    UIBackgroundFetchResultNewData, // 新しいデータが取得出来た  
    UIBackgroundFetchResultNoData, // 新しいデータはなかった  
    UIBackgroundFetchResultFailed // データの取得に失敗した  
} NS_ENUM_AVAILABLE_IOS(7_0);  

結果をiOSに通知すると、次にフェッチするタイミングを決定するのに活用されます。
completionHandlerに何も渡さなかった場合はアプリは動作し続けますが、30秒経過すると停止されます。

動作確認

実際に動かしてみましょう。
先述のようにフェッチ処理はiOSのタイミングで実行されますが、
デバッグ時にはXcodeの Debug > Simulate Background Fetch でテストすることが出来ます。

simulate_backgroundfetch

フェッチが実行されたタイミングでログへ出力されていることを確認して下さい。

おわりに

いかがでしたでしょうか。
iOS 7のマルチタスクの仕組みは他にもありますので、機会があればご紹介したいと思います。