首页 > 其他 > 详细

IOS后台运行 之 Background Fetch

时间:2014-02-25 14:05:38      阅读:401      评论:0      收藏:0      [点我收藏+]

 本文主要教你如何使用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,创建继承与UITableViewController的子类为viewcontroller,在Main.storyboard中,添加一个Navigation Controller,其rootviewcontroller指向viewcontroller,接着添加一些有用的属性:
bubuko.com,布布扣
1 @property (nonatomic) NSMutableArray *objects; 
2 @property (nonatomic) NSArray *possibleTableData; 
3 @property (nonatomic) int numberOfnewPosts; 
4 @property (nonatomic) UIRefreshControl *refreshControl;
bubuko.com,布布扣
 NSMutablearray对象将会被用来在TableView中保存对象列表。在这个教程中,你将不能调用任何服务来获得数据。相反,你将使用possibleTableData数组,并随机从中选择几个对象。整个numberOfnewPosts代表新发布的内容--每次进行请求或者接收后台获取时可用。refrestControl是一个在更新任务时使用的控件。由于不在教程之内,所以本文不会在此展开。

然后转至ViewController.m,第一步加载一些数据。以下代码将会申请内存并创建数据对象,创建一个标题以及初始化refreshControl:
bubuko.com,布布扣
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];  
bubuko.com,布布扣
以上代码将会产生一个提醒,因为我们丢失了insertNewObject method。让我们来解决它。该方法将会产生一个随机数,并且将从日期数组获得对象相同的数据,然后它将会通过新值来更新tableview。
bubuko.com,布布扣
 1 - (void)insertNewObject:(id)sender 
 2 { 
 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     [self.refreshControl endRefreshing]; 
10 } 
bubuko.com,布布扣
当你添加以下方法时,getRandomNumberBetween提醒将会被禁止:
bubuko.com,布布扣
1 -(int)getRandomNumberBetween:(int)from to:(int)to { 
2     return (int)from + arc4random() % (to-from+1); 
3 } 
bubuko.com,布布扣
 为了在 NSArray object上加载对象,我们需要执行TableView委托函数。
bubuko.com,布布扣
 1 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
 2     return 1; 
 3 } 
 4 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
 5     return self.objects.count; 
 6 } 
 7 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
 8     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 
 9     cell.textLabel.text = self.objects[indexPath.row]; 
10     if(indexPath.row < self.numberOfnewPosts){ 
11         cell.backgroundColor = [UIColor yellowColor]; 
12     } 
13     else 
14         cell.backgroundColor = [UIColor whiteColor]; 
15     return cell; 
16 } 
bubuko.com,布布扣
非常简单吧?如果运行项目,你会看到一个类似下图的界面:
bubuko.com,布布扣
2. Background Fetch
现在开始创建Background Fetch功能,首先从Project开始,接着是Capabilities,然后Put Background Modes ON,再选择Background Fetch,如下图所示:
bubuko.com,布布扣
但仅仅做这个是不够的。默认地,app不会调用后台API,所以你需要在AppDelegate.m文件中把以下代码添加至-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method.
bubuko.com,布布扣
1 [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum]; 
bubuko.com,布布扣
这个可以让系统决定何时应该展示新内容。MinimumBackgroundFetchInterval参数值是时间间隔的数值,系统保证两次Fetch的时间间隔不会小于这个值,不能保证每隔这个时间间隔都会调用。这里设置为UIApplicationBackgroundFetchIntervalMinimum,意思是告诉系统,尽可能频繁的调用我们的Fetch方法。现在你的app已经知道启动ackground fetch,让我们告诉它要做些什么。方法-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler将会对你有所帮助。每当执行后台获取时该方法都会被调用,并且应该被包含在AppDelegate.m文件中。以下是完整版本:
bubuko.com,布布扣
 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     } 
10 } 
bubuko.com,布布扣
下一步你应该也把ViewController头文件放进AppDelegate.m类。
bubuko.com,布布扣
1 #import "ViewController.h" 
bubuko.com,布布扣
注意insertNewObjectForFetchWithCompletionHandler并没有被创建,所以还需要在ViewController.h中声明它。
bubuko.com,布布扣
1 - (void)insertNewObjectForFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; 
bubuko.com,布布扣
现在关注执行文件,类似于之前insertNewObject调用的添加。我们使用completionHandler来和系统“交流”,并让它告诉我们app是否现在获取数据,或者当前是否有有效数据。
bubuko.com,布布扣
 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); 
13 } 
bubuko.com,布布扣
完成代码,现在我们模拟一个测试,并验证所有项目都能启动和运行。
 
3. Simulated Background Fetch
创建了Background Fetch后,怎么来方面的模拟和测试呢?有两种方式,一种是在App被挂起后,系统执行Background Fetch,另外一种是App没有在运行,被系统唤醒执行Background Fetch方法。

情况1

直接运行程序,在Xcode的菜单中,选择”Debug” -> “Simulate Background Fetch”,你会发现会先打开App,然后后台挂起,接着执行(void)application: performFetchWithCompletionHandler方法。

bubuko.com,布布扣

情况2

复制(Duplicate)一份当前的Schema,在新的Schema的Options下,选中”Launch due to a background fetch event”,运行这个Schema。

bubuko.com,布布扣

bubuko.com,布布扣

 
 
 

IOS后台运行 之 Background Fetch

原文:http://www.cnblogs.com/easy-coding/p/3564940.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!