iOS后台网络任务

在iOS系统,App的前台运行和后台运行,行为是不同的,iOS操作系统对后台运行做了诸多限制,为了能够让系统运行更流程和更省电。

App的状态如下图:

iOS后台网络任务_第1张图片


对于后台运行,首先需要确定设备是否支持多任务,在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,暂时解决了个问题。但对于有数个请求,执行效率是一个问题。

你可能感兴趣的:(ios,操作系统,异步,background,multitask)