在iOS中應(yīng)用進(jìn)入后臺(tái),系統(tǒng)會(huì)將整個(gè)應(yīng)用當(dāng)前的狀態(tài)以快照的形式保存起來,也就是常說的"墓碑"機(jī)制疙剑。此時(shí)對(duì)應(yīng)的定時(shí)器也就直接被關(guān)閉了戒突,如果我們需要在后臺(tái)保持一段時(shí)間運(yùn)行屯碴,我們就需要做對(duì)應(yīng)的處理。
在iOS中應(yīng)用進(jìn)入后臺(tái)膊存,app都有3分鐘左右的后臺(tái)任務(wù)執(zhí)行時(shí)間导而。 3分鐘后,app會(huì)被iOS強(qiáng)行掛起隔崎。
除了
- 音樂應(yīng)用
- 電話之類
- GPS定位
的app可以保持一個(gè)長久的后臺(tái)運(yùn)行今艺。當(dāng)你提交app到App Store時(shí),蘋果會(huì)審查你的app爵卒,一旦發(fā)現(xiàn)你“濫用”了后臺(tái)API虚缎,你的app將被拒絕。也即是說你在info.plist 設(shè)置這幾種backgroundmode,你的程序必須含有這些功能技潘,你的程序才會(huì)有審核通過遥巴。
一般情況下千康,3分鐘的后臺(tái)時(shí)間足夠我們處理我們的應(yīng)用數(shù)據(jù)了。
定時(shí)器在這3分鐘的時(shí)間內(nèi)保持不間斷的運(yùn)行铲掐。
方法1
在app的代理中添加如下代碼
- (void)applicationDidEnterBackground:(UIApplication *)application {
if ( [self isMutiltaskingSupported] == NO) {
NSLog(@"---> 不支持后臺(tái)多任務(wù)");
return;
}
UIApplication* app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTask;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
bgTask = UIBackgroundTaskInvalid;
}
});
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
bgTask = UIBackgroundTaskInvalid;
}
});
});
}
當(dāng)然你需要判斷你的設(shè)備是否支持后臺(tái)(不支持多任務(wù)情況現(xiàn)在基本可以忽略)
// 判斷當(dāng)前設(shè)備是否支持 后臺(tái)多任務(wù)
- (BOOL)isMutiltaskingSupported{
BOOL result = NO;
if ( [[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) {
result = [[UIDevice currentDevice] isMultitaskingSupported];
}
return result;
}
方法2
在網(wǎng)上搜索了下拾弃,基本上實(shí)現(xiàn)方式都差不多。這里直接代碼貼出摆霉,以備以后查閱
#import "AppDelegate.h"
@interface AppDelegate ()
@property (nonatomic, unsafe_unretained) UIBackgroundTaskIdentifier backgroundTaskIdentifier;
@property (nonatomic, strong) NSTimer * myTimer;
@end
@implementation AppDelegate
// 判斷當(dāng)前設(shè)備是否支持 后臺(tái)多任務(wù)
- (BOOL)isMutiltaskingSupported{
BOOL result = NO;
if ( [[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) {
result = [[UIDevice currentDevice] isMultitaskingSupported];
}
return result;
}
// 定時(shí)器調(diào)用方法
- (void)timerMethod:(NSTimer *)paramSender{
NSTimeInterval backgroundTimeRemanging = [[UIApplication sharedApplication] backgroundTimeRemaining];
if ( backgroundTimeRemanging == DBL_MAX) {
NSLog(@"Background Time Remaining = Undeterminded");
}
//--顯示后臺(tái)任務(wù)還剩余的時(shí)間
NSLog(@"Background Timer Remaining = %.02f Seconds", backgroundTimeRemanging);
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSTimeInterval backgroundTimeRemanging = [[UIApplication sharedApplication] backgroundTimeRemaining];
NSLog(@"backgroundTimeRemanging = %.02f", backgroundTimeRemanging);
if ( [self isMutiltaskingSupported] == NO) {
NSLog(@"---> 不支持后臺(tái)多任務(wù)");
return;
}
self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundTask];
}];
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerMethod:) userInfo:nil repeats:YES];
}
// 任務(wù)完成豪椿,處理釋放對(duì)象
- (void)endBackgroundTask{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
__weak AppDelegate *weakSelf = self;
dispatch_async(mainQueue, ^{
AppDelegate * strongSelf = weakSelf;
if (strongSelf != nil) {
[strongSelf.myTimer invalidate];
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];
strongSelf.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
}
});
}
// 進(jìn)入前臺(tái),停止任務(wù)
- (void)applicationDidBecomeActive:(UIApplication *)application {
if (self.backgroundTaskIdentifier != UIBackgroundTaskInvalid){
[self endBackgroundTask];
}
}
@end
參考鏈接
參考1