Just My Life & My Work

[iOS] 爭取背景執行時間

iOS不像Android,當APP進入背景模式的時候,Android還能暢所欲行,而iOS則會被強制中止,為什麼要這麼做?因為Apple就是要讓裝置省電來做更人性化的事情。那麼iOS是不是就不能在背景模式繼續運行?像是我們下載容量超大的檔案(如100MB),我們一定不會想要枯等看著它下載完,而是會切換到其它APP或其它功能繼續把玩,於是Apple還是會給需要的程式設計師一扇窗!

注意:經資深工程師提點,始知在Info.plist設定background modes是在iOS 7才有,功能上比較像是隨時都有可能需要背景模式時執行,所以若只是想延長背景執行時間來下載大型檔案,就不用設定Info.plist喔!但一定要在AppDelegate.h/.m處理~呵,我參考的部落格文章沒有寫清楚,看來還是要自己實際去驗證,不然就會像我送審的APP被reject~

background mode


其實做法很簡單,在Info-plist的Required background modes設置App communicates with an accessory,接著在AppDelegate.h宣告和AppDelegate.m實作即可。

/**
 Theme: Background Mode to Get more Time
 IDE: Xcode 5
 Language: Objective C
 Date: 103/04/09
 Author: HappyMan
 Blog: https://cg2010studio.wordpress.com/
 */
// AppDelegate.h
@interface HTAppDelegate : UIResponder <UIApplicationDelegate>
{
    UIBackgroundTaskIdentifier bgTask;
}

// AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

    UIApplication *app = [UIApplication sharedApplication];
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSTimeInterval backgroundTimeRemaining = [[UIApplication sharedApplication]backgroundTimeRemaining];

        NSLog(@"after 10s backgroundTimeRemaining: %f", backgroundTimeRemaining);
    });

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSTimeInterval backgroundTimeRemaining = [[UIApplication sharedApplication]backgroundTimeRemaining];

        NSLog(@"after 30s backgroundTimeRemaining: %f", backgroundTimeRemaining);
    });
}

原本進入背景模式後,約十秒的時間就把下載檔案的過程給中止,如今可以多十分鐘來繼續下載!

181127更新

經過實際測試,只延長3分鐘,看Log即可知道剩餘時間⋯⋯

after 10s backgroundTimeRemaining: 169.087568
after 30s backgroundTimeRemaining: 149.852938

以下文章照舊⋯⋯

那如果十分鐘還無法下載完全,該怎麼辦?像是我們會用龜速的3G,此時要下載1GB的超大檔案群,我想至少要花一小時以上的時間,我想到的做法是利用Notification通知使用者,該回來讓APP轉到前景模式,如此又有十分鐘的額度可以消耗!也許還有更好的做法,等著我去發掘~

dropbox background mode2

這是背景模式,Dropbox上傳的狀態。我發現它不到三分鐘就會發出Notification通知呢!

dropbox background mode

這是前景模式,Dropbox上傳的樣子。

最後我想說的是,因為選錯background mode的value被審查委員reject,原因是他認為我們沒有使用external-accessory (App communicates with an accessory),又詳細地說明外部附件需要怎樣的條件,巴拉巴拉⋯⋯

才知道原來是要選擇fetch (App downloads content from the network),才是符合我們APP功能的值⋯⋯如此應該就能審核通過啦!

background mode fetch

我猜想,之所以要填這個值得原因,在於要讓審查委員知道我們需要背景模式做什麼,為了讓設備有長久的電力,勢必要防止開發者誤用不需要的功能。據經驗,似乎選擇任何一個值都能啟用背景模式!

參考:

Comments on: "[iOS] 爭取背景執行時間" (12)

  1. 公司產品需要一次上傳大量相片,用戶可能要花一小時以上,所以再次來研究能否在背景執行更長久~

  2. 您好,我想請問一下是否有辦法持續(永久直到關機)在背景更新地理位置,
    我有找到一些人說用significant-change 可以做到不被suspend,可是有些卻說不行@@
    或許有沒有辦法不被suspend?

    • 後來的iOS有其他方式來達到背景處理,你說的更新地理位置是其中之一,像Dropbox App就可以透過更新地理位置,來繼續備份我的相片! 😀

      至於significant-change我就沒有特別研究了~

      • 是的,你說的沒錯,可是假如照官方教學的standard background location update 我最久只能在背景跑20分鐘,之後就會被系統kill掉@@
        我在網路上爬很多文都沒永久背景更新的方法QQ

        Liked by 1 person

  3. 您好,我想請問一下是否有辦法持續(永久直到關機)在背景更新地理位置,
    我有找到一些人說用significant-change可以做到,有些卻說不行。
    謝謝

  4. 您好! 想請問一下 fetch 是在capabilities Background Mods 勾選的嗎

  5. […] 還有當時想要背景下載,但實際上只作前景下載,而且一次只能下載一個影片,所以使用者要開著螢幕乾等影片下載完畢,後來有加上背景下載(10分鐘內)。 […]

  6. […] 還有當時想要背景下載,但實際上只作前景下載,而且一次只能下載一個影片,所以使用者要開著螢幕乾等影片下載完畢,後來有加上背景下載(10分鐘內)。 […]

  7. 大大你好,小弟想請問一下。
    “我想到的做法是利用Notification通知使用者,該回來讓APP轉到前景模式”
    請問是否可以直接由利用Notification將程式叫到前景,畢竟如果只是通知使用者,怕使用者沒有注意到。

    或是直接每10分鐘將背景程式轉成前景,以延長時間呢?

    • 嗯~除了使用者自己操作APP回到前景外,我還沒聽說我們程式可以控制呢⋯⋯

      Dropbox就是我所說的方法囉~如果連強大的它都沒有做到你說的方法,我想目前也沒有開放類似的API給開發者使用喔~

      換另一個角度來想,Apple若開放這類API,那麼肯定會有許多APP要爭先恐後到前景去!這樣子勢必會耗損大量的電力,因為要是能強制到前景執行,有誰會想要在背景執行呢?

  8. […] 若考慮時間,用3G下載通常比用WiFi下載慢很多,於是下載時間就會拉長,只要有足夠的時間一樣可以下載完畢,然而問題在於下載的狀態又分前景模式和背景模式,前景模式下載只要設備有足夠電源就能完成下載,背景模式下載就要考慮要在限定的時間內下載完畢。可以參考我剛寫的文章:爭取背景執行時間。 […]

回覆給HappyMan 取消回覆

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

標籤雲