因為iOS系統(tǒng)的特殊性驮捍,它不像安卓、Windows等其它操作系統(tǒng)一樣羊娃,能在應用退入后臺還能啟動一些后臺任務處理一些事件。iOS系統(tǒng)在應用退到后臺槽地,也就是按下Home鍵之后迁沫,應用的所有任務會被掛起、暫停捌蚊,因此在這里對它的后臺任務方式作一些記錄集畅。
iOS系統(tǒng)或許是出于電量的考慮吧,因為iPhone手機的電池容量一直都不大缅糟,為了減小功耗挺智,所以它不允許應用退入后臺還留有活的后臺任務。當然并不是說iOS系統(tǒng)不能進行多任務處理窗宦,自iOS7之后赦颇,也有好多種能讓應用在后臺處理任務的方法。
iOS后臺發(fā)展
在一開始的iOS操作系統(tǒng)上赴涵,應用沒有后臺媒怯,按下Home鍵之后,應用就退出了髓窜,設備只能依靠蘋果的APNS與服務器連結(jié)扇苞,重新點擊啟動之后欺殿,應用重新載入;
后來的操作系統(tǒng)鳖敷,有了后臺脖苏,按下Home鍵之后,應用退到后臺定踱,幾秒之后棍潘,會被系統(tǒng)掛起,下次點擊進入崖媚,會出現(xiàn)上次退出的界面(當然在雙擊Home鍵將應用徹底殺死就不能保留數(shù)據(jù)了)亦歉,保留上次的一些操作,但是仍然不能在退入后臺做一些相應的操作畅哑。
再之后就是iOS7之后鳍徽,雖然不能真正的在后臺處理一些東西,但是調(diào)用蘋果的一些API敢课,可以在應用不打開的時候做一些后臺相應的操作阶祭。
后臺處理任務的幾種方式
UIBackgroundTaskIdentifier
這種方式不能讓應用真正的一直在后臺活下去,只能讓應用延緩被掛起的時間直秆,在應用已經(jīng)進入后臺濒募,做一些善后工作,保存一些現(xiàn)場數(shù)據(jù)圾结。
監(jiān)聽UIApplicationDidEnterBackgroundNotification通知瑰剃,或者在applicationDidEnterBackground方法中加入以下代碼。
UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];
__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
[self cleanDiskWithCompletionBlock:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
cleanDiskWithCompletionBlock在該方法中啟動異步線程筝野,立刻返回晌姚,在異步線程中,最后執(zhí)行完成回調(diào)的block歇竟。
Background Mode
Background Fetch
后臺應用刷新挥唠,在手機設置->通用->后臺應用刷新,打開之后焕议,應用可以在后臺不定時的刷新內(nèi)容宝磨。因為這個機制也是由蘋果統(tǒng)一管理,而且調(diào)用時間也是不確定的盅安,所以開發(fā)者很難調(diào)試系統(tǒng)什么時候會分配你時間允許你刷新內(nèi)容唤锉。
打開方法
在XCode->TARGETS->Capabilities->Background Modes
選擇Background Fetch打勾,然后在plist文件中Required background modes添加相應的字段App registers for location updates
在應用啟動的代碼中添加
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
UIApplicationBackgroundFetchIntervalMinimum
UIApplicationBackgroundFetchIntervalNever
關(guān)于刷新的兩個參數(shù)别瞭,一個是盡可能頻繁的刷新窿祥,一個是從來不刷新,刷新頻率由系統(tǒng)來分配決定蝙寨,所以可以應用在實時性不高的場合晒衩。
系統(tǒng)會在刷新應用時号胚,調(diào)用appDelegate中下邊的方法,在下邊方法中處理刷新動作浸遗。
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
//刷新數(shù)據(jù)
completionHandler(UIBackgroundFetchResultNewData);
}
UIBackgroundFetchResultNewData,//刷新到新數(shù)據(jù)
UIBackgroundFetchResultNoData,//沒有新數(shù)據(jù)
UIBackgroundFetchResultFailed//刷新失敗
通過application的屬性去查應用是否開啟后臺刷新功能backgroundRefreshStatus,返回值
UIBackgroundRefreshStatusRestricted, //< unavailable on this system due to device configuration; the user cannot enable the feature
UIBackgroundRefreshStatusDenied, //< explicitly disabled by the user for this application
UIBackgroundRefreshStatusAvailable //< enabled for this application
在實際的IOS7環(huán)境中箱亿,F(xiàn)etch事件是由系統(tǒng)管理的跛锌,app開發(fā)者無法預先知道Fetch事件達到的時機。但XCode也提供了Fetch事件的調(diào)試辦法届惋,在XCode上運行程序后髓帽,在Debug->Simulate Background Fetch.
還有一種情況是app沒有運行(不在前臺也不在后臺),被Fetch事件喚醒執(zhí)行.這種情況的測試方法如下:
Product->Scheme->Edit scheme 在Debug模式選中Options,點選Launch due to a background fetch event脑豹,運行即可
具體可以查官方一些文檔
下邊是官方說明
The system guarantees that it will not wake up your application for a background fetch more frequently than the interval provided. Set to UIApplicationBackgroundFetchIntervalMinimum to be woken as frequently as the system desires, or to UIApplicationBackgroundFetchIntervalNever (the default) to never be woken for a background fetch.
This setter will have no effect unless your application has the "fetch" UIBackgroundMode.
See the UIApplicationDelegate methodapplication:performFetchWithCompletionHandler:
for more.
Remote notifications
蘋果的APNS(Apple Push Notifications Server)連結(jié)著所有的蘋果可接收推送設備郑藏,如果服務器想主動給應用發(fā)送一些消息,必須通過APNS瘩欺。這里主要記錄一些推送在后臺如何接收必盖。
在iOS7之前,推送和應用完全沒有關(guān)系俱饿,設備收到一條推送消息歌粥,應用也完全不知道,而且拍埠,收到推送之后失驶,如果不是點擊推送消息啟動的App,應用啟動之后枣购,也不會回調(diào)下邊的方法
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
所以之前嬉探,經(jīng)常需要應用啟動之后,再去后臺拉取一遍消息棉圈,防止有些數(shù)據(jù)沒有正常接收涩堤。
之后,可以推送來了之后在后臺刷新應用內(nèi)容分瘾,在Background Mode中挑勾Remote notifications,在plist中添加字段App downloads content in response to push notifications定躏,然后在要發(fā)送的數(shù)據(jù)中添加字段content-available:1,否則發(fā)送和普通方式一樣芹敌。
Location updates
后臺定位的應用現(xiàn)在也好多痊远,可以在用戶跑步或者騎行的時候開啟,在后臺記錄下應用跑步的路程氏捞。
開啟方法和上邊基本一樣碧聪,添加Background Mode,然后在info.plist文件中添加App registers for location updates字段液茎。
_locationManager = [[CLLocationManager alloc ]init];
_locationManager.delegate = self;
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.allowsBackgroundLocationUpdates=YES;
[_locationManager requestAlwaysAuthorization];
然后逞姿,應用在進入后臺會回調(diào)下邊方法更新位置
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation