iOS 后臺掛起+解決方案(長時間后臺運行)

一個應用程序的生命周期分為好多種狀態(tài):應用程序失去焦點身冬、應用程序完全獲取焦點、應用程序進入前臺岔乔、應用程序進入后臺酥筝、應用程序關(guān)閉、應用程序被掛起等等雏门。我們簡單說一下嘿歌,應用的前臺狀態(tài)、后臺狀態(tài)以及掛起狀態(tài)茁影。

前臺狀態(tài):但應用程序處于屏幕的第一層宙帝,呈現(xiàn)顯示的時候,就屬于前臺狀態(tài)募闲。

后臺狀態(tài):當前app如果不是作為屏幕中的第一層步脓,呈現(xiàn)顯示給用戶,那么此時app就是后臺狀態(tài)浩螺。
舉例:
鎖屏(包括:當前應用下鎖屏靴患、其他應用下鎖屏、桌面鎖屏)
用戶在使用其他應用app2要出,當前 app1 雖然沒有上滑kill掉鸳君,但是屏幕中的第一層顯示的是app2, 那么app1就是后臺了。

ps:下拉系統(tǒng)菜單 厨幻、上拉系統(tǒng)菜單相嵌,app并沒有進入后臺狀態(tài),只不過app失去了焦點罷了况脆。

掛起狀態(tài):當前app后臺狀態(tài)饭宾,但是不一定掛起,掛起就是關(guān)于app的一切代碼都不再運行了格了。
從測試實踐來看看铆,如果app進入后臺狀態(tài),一般情況下是很快就會被掛起的盛末,也就是進入后臺狀態(tài)后弹惦,里面代碼運行馬上就停止了。


如果需要在app進入到后臺的時候悄但,仍要繼續(xù)運行棠隐,需要怎么辦呢?

兩種情況:
1檐嚣、app進入后臺之后助泽,需要一兩分鐘繼續(xù)一些特殊的操作,特殊操作完成之后才會被掛起。比如:app進入后臺之后嗡贺,上傳用戶使用的操作信息隐解。
2、app進入后臺之后诫睬,需要一直保持運行煞茫。比如:后臺播放音樂。


一摄凡、創(chuàng)建后臺運行任務(app會被延時掛起3分鐘左右)

創(chuàng)建后臺運行任務之后续徽,app并不會被直接掛起,app會繼續(xù)運行到該任務的結(jié)束時間架谎,通過測試炸宵,該任務運行時間大約不到3分鐘,也就175秒左右谷扣。(不過土全,這些時間對于一些簡單的操作,也是足夠了)

例:app進入后臺之后会涎,需要上傳用戶操作數(shù)據(jù)裹匙,上傳完成之后,再讓app掛起末秃。

1概页、定義一個UIBackgroundTaskIdentifier屬性,用于記錄后臺任務的id

@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;

2练慕、在-application:didFinishLaunchingWithOptions:方法中聲明backgroundTaskIdentifier無效惰匙。

// 首先初始化backgroundTaskIdentifier
// 應用程序啟動完成的時候就會調(diào)用AppDelegate的方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    NSLog(@"%s",__func__);
    
    // 初始化backgroundTaskIdentifier
    self.backgroundTaskIdentifier = UIBackgroundTaskInvalid;

    return YES;
}

3、在-applicationDidEnterBackground:方法中創(chuàng)建后臺任務

// 當應用程序進入后臺的時候調(diào)用
- (void)applicationDidEnterBackground:(UIApplication *)application {
    NSLog(@"%s",__func__);
    
    // 進入后臺铃将。若沒有后臺任務项鬼,創(chuàng)建后臺任務。(如果有后臺任務劲阎,不再創(chuàng)建后臺任務)
    if (self.backgroundTaskIdentifier == UIBackgroundTaskInvalid) {

        // 但應用進入后臺時绘盟,要求將用戶的操作數(shù)據(jù)上傳到服務器
        // 因為是上傳用戶數(shù)據(jù),不要求特別精確悯仙。
        // 在本地記錄上次上傳的時候龄毡,如果兩次上傳時間不超過10分鐘,則不需要上傳锡垄。超過10分鐘沦零,才會上傳。
        NSInteger lastDate = [[[NSUserDefaults standardUserDefaults] valueForKey:@"loadingDate"] integerValue];

        NSInteger nowDate = (NSInteger)[[NSDate date] timeIntervalSince1970];

        if (nowDate - lastDate > 600) {
            // 超過了10分鐘货岭,上傳

            // 標記一個長時間運行的后臺任務將開始
            // 通過調(diào)試路操,發(fā)現(xiàn)序攘,iOS給了我們額外的3分鐘(180s)來執(zhí)行這個任務。
            // beginBackgroundTaskWithExpirationHandler一定要和endBackgroundTask方法對應才行寻拂。
            self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
                // 后臺任務到時間之后,會自動執(zhí)行該回調(diào)丈牢。
                // 在該回調(diào)中要執(zhí)行結(jié)束后臺任務方法动漾。
                // 如果操作提前完成辉饱,也可以手動結(jié)束后臺任務。如果,手動結(jié)束后臺任務绵载,則不走改回調(diào)方法。
                [self endBackgroundTask];
            }];

            // 上傳用戶操作數(shù)據(jù)
            [self uploadUserActionDataWithFinished:^(NSInteger status) {
                if (status == 1) {
                    // 上傳用戶操作數(shù)據(jù)成功
                    // 刪除存儲的用戶操作數(shù)據(jù)
                    
                    // 記錄最新的用戶操作數(shù)據(jù)上傳時間
                    [[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInteger:nowDate] forKey:@"loadingDate"];
                    [[NSUserDefaults standardUserDefaults] synchronize];
                    
                    // 最后結(jié)束后臺任務
                } else {
                    // 上傳用戶操作數(shù)據(jù)失敗胶惰,不做任何操作鹉戚,直接結(jié)束后臺任務就行
                }
                
                // 結(jié)束后臺任務
                [self endBackgroundTask];
            }];
        } else {

        }
    }
}

// 結(jié)束后臺任務
- (void)endBackgroundTask {
    if (self.backgroundTaskIdentifier != UIBackgroundTaskInvalid) {
        // 每個對 beginBackgroundTaskWithExpirationHandler:方法的調(diào)用,必須要相應的調(diào)用 endBackgroundTask:方法。這樣师幕,來告訴應用程序你已經(jīng)執(zhí)行完成了粟按。
        // 也就是說,我們向 iOS 要更多時間來完成一個任務,那么我們必須告訴 iOS 你什么時候能完成那個任務。
        // 也就是要告訴應用程序:“好借好還”嘛霹粥。
        // 標記指定的后臺任務完成
        [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];
        // 銷毀后臺任務標識符
        self.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
    }
}

// 上傳用戶操作數(shù)據(jù)
- (void)uploadUserActionDataWithFinished:(void (^)(NSInteger status))finish {
    // 上傳用戶操作
    // 這里寫了一個定時灭将,30秒以后上傳完成,結(jié)束后臺任務
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (finish) {
            finish(1);
        }
    });
}

PS:每個對 beginBackgroundTaskWithExpirationHandler:方法的調(diào)用,必須要相應的調(diào)用 endBackgroundTask:方法后控。這樣庙曙,來告訴應用程序你已經(jīng)執(zhí)行完成了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浩淘,一起剝皮案震驚了整個濱河市捌朴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌张抄,老刑警劉巖砂蔽,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異欣鳖,居然都是意外死亡察皇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門泽台,熙熙樓的掌柜王于貴愁眉苦臉地迎上來什荣,“玉大人,你說我怎么就攤上這事怀酷〉九溃” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵蜕依,是天一觀的道長桅锄。 經(jīng)常有香客問我琉雳,道長,這世上最難降的妖魔是什么友瘤? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任翠肘,我火速辦了婚禮,結(jié)果婚禮上辫秧,老公的妹妹穿的比我還像新娘束倍。我一直安慰自己,他們只是感情好盟戏,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布绪妹。 她就那樣靜靜地躺著,像睡著了一般柿究。 火紅的嫁衣襯著肌膚如雪邮旷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天蝇摸,我揣著相機與錄音婶肩,去河邊找鬼。 笑死貌夕,一個胖子當著我的面吹牛狡孔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜂嗽,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼苗膝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了植旧?” 一聲冷哼從身側(cè)響起辱揭,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎病附,沒想到半個月后问窃,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡完沪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年域庇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片覆积。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡听皿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宽档,到底是詐尸還是另有隱情尉姨,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布吗冤,位于F島的核電站又厉,受9級特大地震影響九府,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜覆致,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一侄旬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧煌妈,春花似錦勾怒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽段只。三九已至腮猖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赞枕,已是汗流浹背澈缺。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留炕婶,地道東北人姐赡。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像柠掂,于是被迫代替她去往敵國和親项滑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355