我正在尝试在 iOS 10 中实现后台获取和刷新。我正在使用 XML 解析来解析数据,然后将其存储在文档目录中的文件中。为了解析 XML,我使用了一个自定义类 (XMLParser),它确认了NSXMLParserDelegate协议。
后台获取工作正常。但是,当我单击刷新按钮以及在 viewDidLoad 中显示刷新的数据时,我遇到了问题。
我在 viewDidLoad 中调用refreshData方法。这是我已经走了多远。
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
//--Set background fetch--//
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
}
...
#pragma mark Background data fetch methods
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
NSDate *fetchStart = [NSDate date];
ArtsViewController *artsViewController = (ArtsViewController *)self.window.rootViewController;
[artsViewController fetchNewDataWithCompletionHandler:^(UIBackgroundFetchResult result) {
completionHandler(result);
NSDate *fetchEnd = [NSDate date];
NSTimeInterval timeElapsed = [fetchEnd timeIntervalSinceDate:fetchStart];
NSLog(@"Background Fetch Duration: %f seconds", timeElapsed);
}];
}
ArtsViewController.h
@interface ArtsViewController : UIViewController <UIPageViewControllerDataSource>
@property BOOL newsAvailable;
-(void)fetchNewDataWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; // No problems here
@end
ArtsViewcontroller.m
@interface ArtsViewController ()
@property (nonatomic, strong) NSArray *arrNewsData;
-(void)refreshData;
-(void)performNewFetchedDataActionsWithDataArray:(NSArray *)dataArray;
@end
...
@implementation ArtsViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self refreshData];
//--Load the file that saves news--//
[self loadNews];
if (_newsAvailable == YES)
{
[self setupPageViewController];
}
else
{
[self showNoNewsMessage];
}
}
...
#pragma mark Data Fetch methods
-(void)refreshData{
XMLParser *xmlParser = [[XMLParser alloc] initWithXMLURLString:ArtsNewsFeed];
[xmlParser startParsingWithCompletionHandler:^(BOOL success, NSArray *dataArray, NSError *error) {
if (success) {
[self performNewFetchedDataActionsWithDataArray:dataArray];
}
else{
NSLog(@"%@", [error localizedDescription]);
}
}];
}
-(void)performNewFetchedDataActionsWithDataArray:(NSArray *)dataArray{
// 1. Initialize the arrNewsData array with the parsed data array.
if (self.arrNewsData != nil) {
self.arrNewsData = nil;
}
self.arrNewsData = [[NSArray alloc] initWithArray:dataArray];
// 2. Write the file and reload the view.
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * docDirectory = [paths objectAtIndex:0];
NSString * newsFilePath = [NSString stringWithFormat:@"%@",[docDirectory stringByAppendingPathComponent:@"arts2"]]; // NewsFile
if (![self.arrNewsData writeToFile:newsFilePath atomically:YES]) {
_newsAvailable = NO;
NSLog(@"Couldn't save data.");
}
else
{
_newsAvailable = YES;
NSLog(@"Saved data.");
[self viewWillAppear:YES];
}
}
-(void)fetchNewDataWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
XMLParser *xmlParser = [[XMLParser alloc] initWithXMLURLString:ArtsNewsFeed];
[xmlParser startParsingWithCompletionHandler:^(BOOL success, NSArray *dataArray, NSError *error) {
if (success) {
NSDictionary *latestDataDict = [dataArray objectAtIndex:0];
NSString *latestTitle = [latestDataDict objectForKey:@"title"];
NSDictionary *existingDataDict = [self.arrNewsData objectAtIndex:0];
NSString *existingTitle = [existingDataDict objectForKey:@"title"];
if ([latestTitle isEqualToString:existingTitle]) {
completionHandler(UIBackgroundFetchResultNoData);
NSLog(@"No new data found.");
}
else{
[self performNewFetchedDataActionsWithDataArray:dataArray];
completionHandler(UIBackgroundFetchResultNewData);
NSLog(@"New data was fetched.");
}
}
else{
completionHandler(UIBackgroundFetchResultFailed);
NSLog(@"Failed to fetch new data.");
}
}];
}
...
#pragma mark IBActions
- (IBAction)reloadNews:(UIBarButtonItem *)sender
{
[self viewDidLoad];
}
我调试了应用程序,发现viewDidLoad执行完成后,数据文件被写入,但视图没有更新。我也尝试在主线程中调用refreshData方法,但没有任何变化。viewDidLoad 完成后,调用showNoNewNews方法。
我怀疑我的逻辑没有错,但实施错了。这里的线程..任何帮助将不胜感激。
更新: 希望这可以帮助那些有类似问题的人......我将逻辑移到了
viewDidLoad
一个不同的方法viewDidLoad
中refreshData
,在[self performNewFetchedDataActionsWithDataArray:dataArray];