Adding Background Fetch Capabilities to Your Apps(在后台获取数据)

  与前一篇介绍app(主动)在后台运行长时间的任务不同,这次是app(被动)让IOS唤醒启动模式

  一般情况,都是打开运行app,然后让app刷新,才能看到新内容,但是这种新的唤醒机制是让app在后台就完成刷新任务,当用户打开app时,新内容已经呈现出

  前提:项目设置-Capabilities-Background Modes:Background fetch 勾选中

  方法:

      //设置唤醒时间

     - (void)setMinimumBackgroundFetchInterval:(NSTimeInterval)minimumBackgroundFetchInterval

      //执行后台获取数据操作

     - (void)application:(UIApplication *)application 

                   performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler

e.g.

 AppDelegate.h

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UIWindow *window;

@property (nonatomic, strong) NSMutableArray *allNewsItems;

@end


 AppDelegate.m

#import "AppDelegate.h"

#import "NewsItem.h" //自定义对象NewsItem 有两属性 NSDate *date , NSString *text;

@implementation AppDelegate

//初始化数组

- (NSMutableArray *) allNewsItems{

    if (_allNewsItems == nil){

        _allNewsItems = [[NSMutableArray alloc] init];      

        /* Pre-populate the array with one item */

        NewsItem *item = [[NewsItem alloc] init];

        item.date = [NSDate date];

        item.text = [NSString stringWithFormat:@"News text 1"];

        [_allNewsItems addObject:item];       

    }

    return _allNewsItems;

}

- (BOOL) application:(UIApplication *)application  didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{  

    //设置唤醒时间,默认UIApplicationBackgroundFetchIntervalNever,稍后要执行performFetchWithCompletionHandler

    [application setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum];   

    return YES;

}

// 后台获取数据

- (void) application:(UIApplication *)application

  performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))

    completionHandler{   

    BOOL haveNewContent = NO;

    [self fetchNewsItems:&haveNewContent];  

    if (haveNewContent){

        completionHandler(UIBackgroundFetchResultNewData); // 成功获取到新数据

    } else {              // UIBackgroundFetchResultFailed 失败

        completionHandler(UIBackgroundFetchResultNoData); // 没有新数据

    }  

}

//参数BOOL带*,表示作为地址存值 

//模拟从服务器获取数据,若是0则无数据,1为有数据

- (void) fetchNewsItems:(BOOL *)paramFetchedNewItems{    

    if (arc4random_uniform(2) != 1){  //arc4random_uniform(n): [0,n) 随机数

        if (paramFetchedNewItems != nil){

            *paramFetchedNewItems = NO;

        }

        return;

    }   

    [self  willChangeValueForKey:@"allNewsItems"]; //KVO模式 willChangeValueForKey -> didChangeValueForKey

    NewsItem *item = [[NewsItem alloc] init];

    item.date = [NSDate date];

    item.text = [NSString stringWithFormat:@"News text %lu",

                 (unsigned long)self.allNewsItems.count + 1];

    [self.allNewsItems addObject:item];    

    if (paramFetchedNewItems != nil){

        *paramFetchedNewItems = YES;

    }    

    [self  didChangeValueForKey:@"allNewsItems"];   

}

.....

@end


  启动界面 - TableViewController.h

@interface TableViewController : UITableViewController

@end


  -TableViewController.m

#import "TableViewController.h"

#import "AppDelegate.h"

#import "NewsItem.h"

@interface TableViewController ()

@property (nonatomic, weak) NSArray *allNewsItems; //注意,这里是用weak

@property (nonatomic, assign) BOOL mustReloadView;

@end

@implementation TableViewController

- (void)viewDidLoad

{

    [super viewDidLoad];   

    AppDelegate *appDelegate = [UIApplication  sharedApplication].delegate;

    self.allNewsItems = appDelegate.allNewsItems;  //因为是weak,所以若appDelegate.allNewsItems后续指向空时,self.allNewsItems也随之

    //注册以接收KVO通知   

    [appDelegate addObserver:self

                  forKeyPath:@"allNewsItems"

                     options:NSKeyValueObservingOptionNew

                     context:NULL];    

    [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(handleAppIsBroughtToForeground:)

                                                 name:UIApplicationWillEnterForegroundNotification

                                               object:nil];

}

//当keyPath对应的值改变时。。必须先注册(addObserver:forKeyPath:options:context)

//在AppDelegate.m文件中fetchNewsItems时,有didChangeValueForKey,所以在值改变时此处会执行

- (void) observeValueForKeyPath:(NSString *)keyPath

                       ofObject:(id)object

                         change:(NSDictionary *)change

                        context:(void *)context{    

    if ([keyPath isEqualToString:@"allNewsItems"]){

        if ([self isBeingPresented]){

            [self.tableView reloadData];

        } else {

            self.mustReloadView = YES;

        }

    }   

}

- (void) handleAppIsBroughtToForeground:(NSNotification *)paramNotification{

    if (self.mustReloadView){

        self.mustReloadView = NO;

        [self.tableView reloadData];

    }

}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return self.allNewsItems.count;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    

    static NSString *CellIdentifier = @"Cell";    

    UITableViewCell *cell = [tableView

                             dequeueReusableCellWithIdentifier:CellIdentifier

                             forIndexPath:indexPath];    

    NewsItem *newsItem = self.allNewsItems[indexPath.row];   

    cell.textLabel.text = newsItem.text;   

    return cell;

}

//取消相关注册

- (void) dealloc{

    AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;

    [appDelegate removeObserver:self forKeyPath:@"allNewsItems"];

    [[NSNotificationCenter defaultCenter] removeObserver:self];

}

@end




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值