`

实战iOS7之后台多任务

阅读更多
在WWDC2013中 水果公司把iOS7的中后台多任务单独开出来一个Session讲述(Session 204 What’s New with Multitasking),其对后台多任务的改动如下:
  • 1. 改变了后台任务的运行方式(Background Task)
  • 2. 增加了后台获取(Background Fetch)
  • 3. 增加了推送唤醒(静默推送,Silent Remote Notifications)
  • 4. 增加了后台传输(NSURLSession的BackgroundSession)

开发者如果可以更好的利用这些特性,可以很大的提升自己的应用体验,比方说,使用后台获取特性,在你打开微博之前,最新的微博已经自动刷出来,不需要用户再手动刷一次。

知识点



用法
后台任务
后台任务是任务级别的配置,它的作用是当应用切换到后台后仍能保持一段运行时间以完成一些耗时的任务,通常这个时间比较短,不适宜做耗时大的操作,用法

1.启动后台任务
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
	...
    }];
2.结束后台任务
[[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];


后台获取
后台获取是应用级配置,其可以帮助应用在合适的时候触发一次后台获取,我们只能配置最快什么时候做一次获取,但是具体什么时候做,这得看设备的心情,不过水果公司说,其会根据用户习惯做后台获取,比方说你每天中午12:00使用这个应用,那么它就会在11:50给你做一次后台获取,是不是这么神,有待检验。用法:

1.在info.list中为应用配置后台获取
2.在系统启动配置后台获取的(最快)频率
3.在AppDelegate中实现方法-application:performFetchWithCompletionHandler: 执行后台获取代码

远程唤醒通知
在iOS7中,对远程通知进行了改造,新的远程通知可以附带上一些参数,这样可以减少一些不必要的网络请求,提升性能.它使设备可以接收远端推送后让系统唤醒设备和我们的后台应用,并先执行一段代码来准备数据和UI,然后再提示用户有推送。这时用户如果解锁设备进入应用后将不会再有任何加载过程,新的内容将直接得到呈现。注意,因为,每一次远程通知都会唤醒设备,为了保证设备续航,水果公司对发送通知的频率是有限制的,尽量少用。用法

1.为应用配置使用远程推送
2.使用最新格式的notification
{
    "aps" : {
        "content-available" : 1
    },
    "content-id" : 42
}
3.AppDelegate中配置delegate方法处理notification:
-(void)application:(UIApplication *)application 
  didReceiveRemoteNotification:(NSDictionary *)userInfo 
        fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

NSURLSession之BackgroundSession
这个主要就是用来处理大数据量的下载的,其保证应用即使在后台也不影响数据的上传和下载。用法:
1.创建NSURLSession的backgrounSession,并对其进行配置(参见上一篇文章)
2.使用该Session启动一个数据传输任务。
3.在AppDelegate中实现方法告诉应用:
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier
  completionHandler:(void (^)())completionHandler

4.在具体的ViewController中实现NSURLSessionTask的Delegate方法,根据任务完成或出错的情况对UI进行更新:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                              didFinishDownloadingToURL:(NSURL *)location;
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                           didCompleteWithError:(NSError *)error;

一旦后台传输的状态发生变化(包括正常结束和失败)的时候,应用将被唤醒并运行appDelegate中的回调,接下来NSURLSessionTask的Delegate方法将在后台被调用

实战
这儿我实现了一个后台获取的Demo,我使用后台获取去获取一张图片,显示在页面上。下面是演示效果:



实现代码:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //设定BackgroundFetch的频率
    [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
…
}

#pragma mark - backgroundFetch delegates
-(void) application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    //当后台获取被触发时,或调用下面的代码,这儿我直接去调用MainViewController的方法去刷新UI。
    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
    MainViewController *mainViewController  = (MainViewController *)navigationController.topViewController;
    [mainViewController fetchImageWithCompletionHandler:completionHandler];
    //修改Icon的bageNumber提醒后台又刷新,强迫症者慎用
    [UIApplication sharedApplication].applicationIconBadgeNumber +=1;
}


MainViewController.m
-(void)fetchImageWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    //调用子UIViewController的方法刷新UI
    NSLog(@"main controller called fetch");
    [self.backgroundFetchViewController initImageViewWithCompletionHandler:completionHandler];
}

BackgroundFetchViewController.m
#import "BackgroundFetchViewController.h"

@interface BackgroundFetchViewController ()

@end

@implementation BackgroundFetchViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(NSURL *)createDirectoryForDownloadItemFromURL:(NSURL *)location
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *urls = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
    NSURL *documentsDirectory = urls[0];
    return [documentsDirectory URLByAppendingPathComponent:[location lastPathComponent]];
}

//把文件拷贝到指定路径
-(BOOL) copyTempFileAtURL:(NSURL *)location toDestination:(NSURL *)destination
{
    
    NSError *error;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:destination error:NULL];
    [fileManager copyItemAtURL:location toURL:destination error:&error];
    if (error == nil) {
        return true;
    }else{
        NSLog(@"%@",error);
        return false;
    }
}

- (void)showImageWithURL:(NSURL *)imageURL
{
    UIImage *image = [UIImage imageWithContentsOfFile:[imageURL path]];
    self.imageView.image = image;
    self.imageView.contentMode = UIViewContentModeScaleAspectFit;
    self.imageView.hidden = NO;
}

-(void) initImageViewWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"Background Fetch View Controller called");
    NSURLSessionDownloadTask *task = [[self session] downloadTaskWithRequest:[self request] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
        if (!error) {
//            获取新的数据,刷新UI
            NSURL *imageURL = [self createDirectoryForDownloadItemFromURL:location];
            NSLog(@"Fetch image successful, %@",[imageURL path]);
            [self copyTempFileAtURL:location toDestination:imageURL];
            [self showImageWithURL:imageURL];
//            调用compeletionHandler, 系统会刷新应用在App Switcher中的UI
            completionHandler(UIBackgroundFetchResultNewData);
        }else{
            NSLog(@"Fetch data failed");
            completionHandler(UIBackgroundFetchResultFailed);
        }
    }];
    [task resume];
    
}


- (NSURLSession *)session
{
    //创建NSURLSession
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession  *session = [NSURLSession sessionWithConfiguration:sessionConfig];
    return session;
}

- (NSURLRequest *)request
{
    //创建请求
    NSURL *url = [NSURL URLWithString:@"http://upload.wikimedia.org/wikipedia/commons/e/e0/Steve_Jobs_with_the_Apple_iPad_no_logo_(cropped).jpg"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    return

所有代码在这儿:https://github.com/xianlinbox/iOS7_New
参考文章:
http://www.shinobicontrols.com/blog/posts/2013/09/24/ios7-day-by-day-day-3-background-fetch
http://www.objc.io/issue-5/multitasking.html
http://onevcat.com/2013/08/ios7-background-multitask/
  • 大小: 177.5 KB
  • 大小: 7.2 MB
3
0
分享到:
评论

相关推荐

    实战iOS7之后台多任务 - 我期望的世界 - ITeye技术网站1

    总的来说,iOS7之后的后台多任务机制为开发者提供了强大的工具,能够在不影响用户体验的前提下,进行数据同步、任务执行等操作。理解并合理利用这些特性,能极大地提高应用的效率和用户满意度。在实际开发中,需要...

    iOS 6 编程实战

    此外,iOS 6的多任务处理功能也有所增强,比如后台模式,使得应用程序在后台也能执行特定任务,如音频播放或定位服务。开发者需要学习如何合理利用这些特性,以提供更流畅的用户体验。 总之,《iOS 6编程实战》是一...

    iOS 7 编程实战 带书签目录 高清完整版

    - **多线程与异步编程**:利用GCD (Grand Central Dispatch) 和NSOperationQueue等技术实现多任务处理。 - **网络编程**:包括HTTP请求、JSON解析等内容,学习如何与服务器端进行通信。 - **Core Animation**:介绍...

    iOS7 编程实战 代码 全

    iOS7开始支持后台多任务处理,如后台应用刷新和声音播放。开发者可以利用`UIApplication`的`beginBackgroundTaskWithExpirationHandler:`方法和`backgroundModes`键在Info.plist中声明后台功能。 六、Motion API ...

    iOS 开发范例实战宝典(进阶篇)

    在iOS开发领域,实战经验是提升技能的关键。"iOS开发范例实战宝典(进阶篇)"聚焦于实际应用中的各种技术,旨在帮助开发者掌握更高级的iOS开发技巧。这本书深入探讨了图形图像处理、数据可视化、网络交互、媒体播放...

    ios5实战 byTotorials

    5. **多任务处理**:iOS 5对多任务处理进行了优化,使得应用程序在后台也能执行特定任务,如音乐播放、位置更新和下载。书中将涵盖如何利用多任务特性来增强应用的功能。 6. **其他技术**:除了上述核心特性外,书...

    从零开始学iOS7开发系列教程-事务管理软件开发实战

    这个教程涵盖了从基础到进阶的多个方面,旨在帮助初学者掌握iOS7开发的核心技术,并通过实战项目——开发一个事务管理软件,来实践所学知识。教程共分为九个章节,每个章节都包含理论讲解和实际操作,旨在确保学习者...

    iOS6 编程实战(英)

    5. **多任务处理**:iOS 6引入了多任务特性,允许应用在后台运行,如音乐播放、位置更新等。了解如何利用这些特性能提高用户体验。 6. **地图服务**:iOS 6推出了自家的地图服务,取代了之前使用的Google Maps,...

    ios6开发进阶与实战源码

    7. **多任务处理**:iOS6开始支持后台应用刷新和声音播放,源码中可能包含这些功能的实现,让开发者学习如何在后台执行任务。 8. **Game Kit和Game Center**:iOS6对Game Kit进行了更新,强化了Game Center的功能。...

    iOS7 典型实例大全源代码 上册

    7. **Core Data**:iOS7对Core Data进行了优化,包括更好的多线程支持和性能提升。开发者应了解如何高效地使用Core Data进行数据持久化。 8. **Background App Refresh**:此功能允许应用程序在后台执行任务,如...

    ios实战项目案例教程

    在iOS开发领域,实战项目是提升技能和理解应用构建过程的关键。"iOS实战项目案例教程"提供了一系列关于iOS开发的经典应用实例,旨在帮助开发者深入学习并掌握iOS开发技术。本教程面向那些对iOS编程有着浓厚兴趣,...

    iOS 4 实战 iOS 4 in Action J.Harrington+源代码

    iOS 4是苹果公司为iPhone、iPad和iPod touch设备推出的操作系统版本,它带来了许多新特性和改进,包括多任务处理、Game Center、iAd广告平台、FaceTime视频通话以及更强大的开发者工具等。这些新功能为开发者提供了...

    iOS开发范例实战宝典(进阶篇)

    《iOS开发范例实战宝典(进阶篇)》是一本专门为iOS开发者设计的实践指导书籍,旨在帮助读者深入理解并掌握iOS应用开发的核心技术。这本书涵盖了从基础到高级的各种主题,提供了丰富的实例来帮助读者巩固理论知识并...

    iOS精美后台闹钟时钟

    2. **多任务处理(Background Execution)**:iOS设备对后台运行有严格的限制,但为了支持闹钟功能,我们需要确保应用能在后台执行。这需要理解iOS的后台模式,如声音和提醒服务后台模式,使得应用在特定条件下能...

    ios 7 programming cookbook 英文版

    7. **Multitasking**:iOS 7引入了后台多任务处理,允许应用在后台执行任务,如音频播放、位置更新等。开发者将学习如何正确实现和优化多任务功能。 8. **Notification Center**:iOS 7的通知中心允许用户在任何...

    iOS 7 Programming Cookbook

    2. **多任务处理**:iOS 7开始支持后台应用刷新和后台传输,开发者可以学习如何实现应用在后台时仍能更新内容,如使用Background Fetch和Remote Notifications来保持应用数据的实时性。 3. **通知机制**:iOS 7的...

    iOS高级实战demo

    在iOS高级实战中,开发者经常会接触到一系列复杂但重要的技术,这些技术可以显著提升应用的性能、用户体验和安全性。本资源包包含了一些关键知识点的示例代码,非常适合希望进阶的iOS开发者进行学习和实践。 首先,...

    ios 7 programming cookbook source code

    首先,iOS 7是Apple公司推出的操作系统版本,带来了诸多新特性,如控制中心、后台多任务处理、扁平化设计等。开发者需要掌握这些新特性,以便在应用中充分利用,提升用户体验。 其次,Xcode 5是开发iOS应用的主要...

Global site tag (gtag.js) - Google Analytics