iOS後臺網絡任務

在iOS系統,App的前臺運行和後臺運行,行爲是不同的,iOS操作系統對後臺運行做了諸多限制,爲了能夠讓系統運行更流程和更省電。

App的狀態如下圖:



對於後臺運行,首先需要確定設備是否支持多任務,在iOS4.0 之前是否沒辦法做到多任務的,不過現在iOS4.0的設備已經很少了。

    UIDevice* device = [UIDevice currentDevice];
    BOOL backgroundSupported = NO;
    if ([device respondsToSelector:@selector(isMultitaskingSupported)])
        backgroundSupported = device.multitaskingSupported;

有三種方式可以在App切後臺後,獲得後臺執行,第一種是執行有限時間的後臺任務,第二種通過本地通知執行定時任務,第三種執行長運行後臺任務(系統開發的音樂播放等)

第一種,使用beginBackgroundTaskWithExpirationHandler:在applicationDidEnterBackground裏調用

- (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.
     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.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        // Do the work associated with the task, preferably in chunks.
        // your code
        NSLog(@" %f",application.backgroundTimeRemaining);
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });

}
第二種,使用本地系統通知

- (void)scheduleAlarmForDate:(NSDate*)theDate
    {
        UIApplication* app = [UIApplication sharedApplication];
        NSArray*    oldNotifications = [app scheduledLocalNotifications];
        // Clear out the old notification before scheduling a new one.
        if ([oldNotifications count] > 0)
            [app cancelAllLocalNotifications];
        // Create a new notification.
        UILocalNotification* alarm = [[UILocalNotification alloc] init];
        if (alarm)
        {
            alarm.fireDate = theDate;
            alarm.timeZone = [NSTimeZone defaultTimeZone];
            alarm.repeatInterval = 0;
            alarm.soundName = @"alarmsound.caf";
            alarm.alertBody = @"Time to wake up!";
            
            [app scheduleLocalNotification:alarm];
        }
    }

第三種調用系統指定的後臺運行任務,有一下這些,例如GPS 音樂等

      Apps that play audible content to the user while in the background, such as a music player app

      Apps that record audio content while in the background.

      Apps that keep users informed of their location at all times, such as a navigation app

      Apps that support Voice over Internet Protocol (VoIP)

      Apps that need to download and process new content regularly

      Apps that receive regular updates from external accessories


在項目中,我用的是第一種,大致就是每次在app在切後臺,發送一些網絡請求去server,遇到個問題,就是如果採用異步方式發送請求時,未等App收到回覆,程序已切到後臺,所以把其改成同步請求,如:

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
    NSError *error;
    NSURLResponse *response;
    NSData *data= [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
可正常收到response,暫時解決了個問題。但對於有數個請求,執行效率是一個問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章