iOS 7 SDK: 如何使用后台获取(Background Fetch)

转载自:http://www.cocoachina.com/industry/20131114/7350.html


本文主要教你如何使用iOS 7 SDK多任务处理API--Background Fetch。我们生活在一个社交化的世界中,大部分用户都安装了几个社交类app,但是每次用户打开app,他们必须要等待app加载更新才能看到更新


 本文主要教你如何使用iOS 7 SDK多任务处理API--Background Fetch。我们生活在一个社交化的世界中,大部分用户都安装了几个社交类app,但是每次用户打开app,他们必须要等待app加载更新才能看到跟更多最新的内容,对于越来越没耐心的用户来说这一点无疑令人非常痛苦。现在,iOS 7的后台获取(Background Fetch)可以很好地解决这个问题,在用户打开应用之前,app就能自动更新获取内容。

 
以检测流量的app为例来说明Background Fetch如何工作。如果你会在每天早上查看应用,我们假设在8:20 AM,,你的iOS app必须在当时获得信息。现在如果操作系统知道你将会在8:20 AM左右使用app,那么它可以提前获得数据,从而提供更好的用户体验。
 
关于iOS 7多任务执行更全面的概览可参看我们的主题“ iOS 7 SDK: Multitasking Enhancements”。以下我们将会以一个实例工程来演示如何使用后台获取(Background Fetch)。
 
1.项目安装
第一步是创建一个iOS 7项目,并选择单视图app,接着添加一些有用的属性:
 
 
  1. @property (nonatomic) NSMutableArray *objects; 
  2. @property (nonatomic) NSArray *possibleTableData; 
  3. @property (nonatomic) int numberOfnewPosts; 
  4. @property (nonatomic) UIRefreshControl *refreshControl; 
 NSMutablearray对象将会被用来在TableView中保存对象列表。在这个教程中,你将不能调用任何服务来获得数据。相反,你将使用possibleTableData数组,并随机从中选择几个对象。整个numberOfnewPosts代表新发布的内容--每次进行请求或者接收后台获取时可用。refrestControl是一个在更新任务时使用的控件。由于不在教程之内,所以本文不会在此展开。
 
在Main.storyboard中,把ViewController改为UITableViewController,下一步,点击UITableViewController,转到Editor > Embed in > Navigation Controller。记得把自定义类设置为ViewController。然后转至ViewController.m,第一步加载一些数据。以下代码将会申请内存并创建数据对象,创建一个标题以及初始化refreshControl:
 
 
  1. self.possibleTableData = [NSArray arrayWithObjects:@"Spicy garlic Lime Chicken",@"Apple Crisp II",@"Eggplant Parmesan II",@"Pumpkin Ginger Cupcakes",@"Easy Lasagna", @"Puttanesca", @"Alfredo Sauce", nil]; 
  2. self.navigationItem.title = @"Delicious Dishes"
  3. self.refreshControl = [[UIRefreshControl alloc] init]; 
  4. [self.refreshControl addTarget:self action:@selector(insertNewObject:) forControlEvents:UIControlEventValueChanged]; 
  5. [self.tableView addSubview:self.refreshControl]; 
 
以上代码将会产生一个提醒,因为我们丢失了insertNewObject method。让我们来解决它。该方法将会产生一个随机数,并且将从日期数组获得对象相同的数据,然后它将会通过新值来更新tableview。
 
 
  1. - (void)insertNewObject:(id)sender 
  2.     self.numberOfnewPosts = [self getRandomNumberBetween:0 to:4]; 
  3.     NSLog(@"%d new fetched objects",self.numberOfnewPosts); 
  4.     for(int i = 0; i < self.numberOfnewPosts; i++){ 
  5.         int addPost = [self getRandomNumberBetween:0 to:(int)([self.possibleTableData count]-1)]; 
  6.         [self insertObject:[self.possibleTableData objectAtIndex:addPost]]; 
  7.     } 
  8.     [self.refreshControl endRefreshing]; 
当你添加以下方法时,getRandomNumberBetween提醒将会被禁止:
 
 
  1. -(int)getRandomNumberBetween:(int)from to:(int)to { 
  2.     return (int)from + arc4random() % (to-from+1); 
 为了在 NSArray object上加载对象,我们需要执行TableView委托函数。
 
 
  1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
  2.     return 1; 
  3. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
  4.     return self.objects.count; 
  5. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
  6.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 
  7.     cell.textLabel.text = self.objects[indexPath.row]; 
  8.     if(indexPath.row < self.numberOfnewPosts){ 
  9.         cell.backgroundColor = [UIColor yellowColor]; 
  10.     } 
  11.     else 
  12.         cell.backgroundColor = [UIColor whiteColor]; 
  13.     return cell; 
非常简单吧?如果运行项目,你会看到一个类似下图的界面:
2. Background Fetch
现在开始创建Background Fetch功能,首先从Project开始,接着是Capabilities,然后Put Background Modes ON,再选择Background Fetch,如下图所示:
但仅仅做这个是不够的。默认地,app不会调用后台API,所以你需要在AppDelegate.m文件中把以下代码添加至-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method.
 
 
  1. [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum]; 
这个可以让系统决定何时应该展示新内容。现在你的app已经知道启动ackground fetch,让我们告诉它要做些什么。方法-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler将会对你有所帮助。每当执行后台获取时该方法都会被调用,并且应该被包含在AppDelegate.m文件中。以下是完整版本:
 
 
 
  1. -(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { 
  2.     UINavigationController *navigationController = (UINavigationController*)self.window.rootViewController; 
  3.     id topViewController = navigationController.topViewController; 
  4.     if ([topViewController isKindOfClass:[ViewController class]]) { 
  5.         [(ViewController*)topViewController insertNewObjectForFetchWithCompletionHandler:completionHandler]; 
  6.     } else { 
  7.         NSLog(@"Not the right class %@.", [topViewController class]); 
  8.         completionHandler(UIBackgroundFetchResultFailed); 
  9.     } 
下一步你应该也把ViewController头文件放进AppDelegate.m类。
 
 
  1. #import "ViewController.h" 
注意insertNewObjectForFetchWithCompletionHandler并没有被创建,所以还需要在ViewController.h中声明它。
 
 
 
  1. - (void)insertNewObjectForFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; 
现在关注执行文件,类似于之前insertNewObject调用的添加。我们使用completionHandler来和系统“交流”,并让它告诉我们app是否现在获取数据,或者当前是否有有效数据。
 
 
  1. - (void)insertNewObjectForFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { 
  2.     NSLog(@"Update the tableview."); 
  3.     self.numberOfnewPosts = [self getRandomNumberBetween:0 to:4]; 
  4.     NSLog(@"%d new fetched objects",self.numberOfnewPosts); 
  5.     for(int i = 0; i < self.numberOfnewPosts; i++){ 
  6.         int addPost = [self getRandomNumberBetween:0 to:(int)([self.possibleTableData count]-1)]; 
  7.         [self insertObject:[self.possibleTableData objectAtIndex:addPost]]; 
  8.     } 
  9.     /* 
  10.      At the end of the fetch, invoke the completion handler. 
  11.      */ 
  12.     completionHandler(UIBackgroundFetchResultNewData); 
完成代码,现在我们模拟一个测试,并验证所有项目都能启动和运行。
 
3. Simulated Background Fetch
如果想确定是否每件事都已经配置好了,你需要编辑Schemes,在Schemes列表点击Manage Schemes选项,如下:
 
在Schemes管理区你可以复制app的scheme:
 
复制后scheme会在新窗口展示。你可在Options标签下更改它的名称。选择“Launch due to a background fetch event”框,并在所有窗口中点击“OK”。
 
接着,使用复制的scheme运行app。注意app不会在前台打开,但是它应该已经获得了一些内容。如果打开app,并且几个recipe已生效,那就说明操作已经成功了。为了使用后台获取功能,你也可以从Xcode菜单的Debug > Simulate Background Fetch开始。

************************************************

转自:http://www.tekuba.net/program/320/


开启Background Fetch支持

在XCode->TARGETS->Capabilities->Background Modes打开并添加Background Fetch.

同时在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中添加:

[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];

MinimumBackgroundFetchInterval参数值是两次Fetch时间间隔,不能保证每隔这个时间间隔都会调用。这里设置为UIApplicationBackgroundFetchIntervalMinimum,意思是尽可能频繁的调用我们的Fetch方法。

增加实现Fetch方法

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{};

每次系统Fetch时都会调用该方法,我们可以在该方法中做刷新数据等操作,操作执行完成以后要调用completionHandlerblock(),比如:completionHandler(UIBackgroundFetchResultNewData);文档中说系统会根据completionHandler(执行的时间)来估计此次Fetch的耗电等。如果耗时耗电比较多,可能会降低被调用的次数。但这个方法也不是不限时执行的,说是有30s的时间来执行操作。completionHandler有三个参数:

UIBackgroundFetchResultNewData 成功拉取数据

UIBackgroundFetchResultNoData 没有新数据

UIBackgroundFetchResultFailed 拉取数据失败或者超时

模拟Fetch事件

在实际的IOS7环境中,Fetch事件是由系统管理的,app开发者无法预先知道Fetch事件达到的时机。但XCode也提供了Fetch事件的调试办法,在XCode上运行程序后,在Debug->Simulate Background Fetch.

还有一种情况是app没有运行(不在前台也不在后台),被Fetch事件唤醒执行.这种情况的测试方法如下:

Product->Scheme->Edit scheme 在Debug模式选中Options,点选Launch due to a background fetch event,运行即可。

]可以观察到当Fetch事件到来时,app先进入后台,再执行- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{}。

判断设备是否开启后台应用程序刷新功能

 UIAlertView * alertView = [[UIAlertViewalloc]initWithTitle:nil message:@"你没有开启后台刷新,请在设置-》通用-》应用程序后台刷新中开启" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
  [alertView show];


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值