Background Fetch 是iOS7帶來的非常Cool的新特性,開啓Background Fetch的App會被系統在合適的時機執行後臺任務的代碼。比如這個場景:你每天晚上10點會通過自己的RSS閱讀器App來閱讀,系統可能會在10點之前執行App中設定的下載RSS最新資源的任務,當你打開RSS閱讀器App的時候就顯示出最新的內容。實現Background Fetch的步驟也是非常的簡單,下面就來看一下。
1、開啓Background Fetch
給一個App開啓Background Fetch非常的簡單,可以總結爲三個步驟:
Step 1
進入Project
設置 -> Capabilities
->
設置Background Modes
爲ON -> 選中Background
Fetch
Step 2
在ApplicationDelegate類的
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
方法中,添加下面的代碼:
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
MinimumBackgroundFetchInterval
參數值是時間間隔的數值,系統保證兩次Fetch的時間間隔不會小於這個值,不能保證每隔這個時間間隔都會調用。這裏設置爲UIApplicationBackgroundFetchIntervalMinimum
,意思是告訴系統,儘可能頻繁的調用我們的Fetch方法。
Step 3
開始實現我們的Fetch方法,在ApplicationDelegate類中加入下面這個方法:
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
SSViewController *ssVC = (SSViewController*)self.window.rootViewController;
if ([ssVC isKindOfClass:[SSViewController class]]) {
NSLog(@"is SSViewController");
ssVC.indexValue ++;
completionHandler(UIBackgroundFetchResultNewData);
} else {
NSLog(@"is not SSViewController");
completionHandler(UIBackgroundFetchResultFailed);
}
}
這個方法每次系統執行Background Fetch時都會被調用,可以在這裏下載網絡數據等。執行完下載任務之後,需要立即調用completionHandler
block。文檔中提到系統用耗時來估算這次fetch的電量消耗和數據消耗,如果耗時比較長,未來可能減少被調用的機會。completionHandler
block可以用的參數值有下面三個:
- UIBackgroundFetchResultNewData 拉取數據OK
- UIBackgroundFetchResultNoData 沒有新數據
- UIBackgroundFetchResultFailed 拉取數據失敗或者超時
文檔中也提到,當這個方法被調用後,App有30s的時間來執行下載操作,然後馬上執行completionHandler
block,就是說最好能把下載任務的耗時限制在30s內,超過30s的,App會被系統掛起。
在剛纔給出的方法中,爲了方便測試只是更新了ViewController的一個參數值,這個參數值會直接反應到界面上,方面測試。
有個小細節是假如Background Fetch方法更新了UI的話,系統會刷新Home鍵切換App界面中的縮略圖。
2、模擬Background Fetch
創建了Background Fetch後,怎麼來方面的模擬和測試呢?有兩種方式,一種是在App被掛起後,系統執行Background Fetch,另外一種是App沒有在運行,被系統喚醒執行Background Fetch方法。
情況1
直接運行程序,在Xcode的菜單中,選擇”Debug” -> “Simulate Background Fetch”,你會發現會先打開App,然後後臺掛起,接着執行(void)application:
performFetchWithCompletionHandler
方法。
情況2
複製(Duplicate)一份當前的Schema,在新的Schema的Options下,選中”Launch due to a background fetch event”,運行這個Schema。
3、Remote Notifications & Background Transfer Service
Background Fetch適用於定期檢查更新數據,如果想從服務端推送一條消息告訴客戶端來執行某些操作的話,可以使用Remote Notifications,它和普通的Push Notification很相似,不同的是推送時的Payload不太一樣以及客戶端收到通知之後會執行一個的方法,和Background Fetch一樣有30s的時間來做事情。你看到這裏一定有個疑問,如果任務在30s內不能完成怎麼破?比如下載音視頻文件。Background Transfer Service閃亮出場了,感興趣的話可以參考Ref裏的第三條鏈接裏的內容。
Ref
- iOS 7 SDK: Working with Background Fetch
- iOS 7 by Tutorials
- iOS 7 SDK: Multitasking Enhancements 延伸閱讀 : About Remote Notifications & Background Transfer Service
完鳥,如果有寫的不對的地方,歡迎小夥伴們指正,Have fun~
原文鏈接:http://joeyio.com/ios/2013/10/27/background-fetch/