0

我正在尝试在 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一个不同的方法viewDidLoadrefreshData,在 [self performNewFetchedDataActionsWithDataArray:dataArray];

4

0 回答 0