简体   繁体   中英

iOS updating UI during a background fetch

In my app, I'm performing a background fetch.

In AppDelegate: didFinishLaunchingWithOptions method, I'm loading a class:

UIStoryboard *storyb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    _syncController = [storyb instantiateViewControllerWithIdentifier:@"SyncStatusViewController"];

and in

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

[HHCServerCall callServerWithFunction:@"xxx" withMethod:@"POST" headers:nil andParameters:bodyPArams success:^(BOOL success, id response) {

            NSError *parseError = nil;
            NSString *xmlString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
            NSDictionary *xmlDictionary = [XMLReader dictionaryForXMLString:xmlString error:&parseError];
            int cntCountRecieved = /...;

            if (cntCountRecieved > 0) {
                [self.syncController startDownload];
                completionHandler(UIBackgroundFetchResultNewData);
            }else{
                completionHandler(UIBackgroundFetchResultNoData);
            }

        } failure:^(NSError *error, NSInteger statusCode) {
            NSLog(@"failure config call %@",error);

        }];
}

The startDOwnload method in the _syncController is a NSURLSessionDownloadTask ,

Delegate method to receive data in sync controller class:

- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location{

 //process data 
    [self updateContactsLabel:processedCount];
}


-(void)updateContactsLabel:(int)count{

    dispatch_async(dispatch_get_main_queue(), ^{
        int totalContactCount = (int)[[NSUserDefaults standardUserDefaults]integerForKey:@"totalContacts"];
        float tmp = (float)count;
        if (self.contactsProgressView.hidden) {
            self.contactsProgressView.hidden = NO;
        }
        self.contactsProgressView.progress = tmp/totalContactCount;
        self.contactsReceived.text = [NSString stringWithFormat:@"%d",count];
    });
}

The count value is properly incrementing as expected, but all the UIElements are nil in this method, even after I go to that particular class.

What I dont understand is, when I actually go to the sync class , and I could see all the elements loaded on screen, and I see updateContactsLabel : is being called properly and in that method the UIElements are nil, even after I go to that class.

Those UIElements are not nil, when debugged in viewWillAppear of SyncController class, but they are nil in the updateContactsLabel: method which is present in the same SyncController class, which gets called continuously till the download finishes.

Is it because the updateContacts : method was called on syncController class where UIElements are not loaded yet ?

How can I make the UIElements update properly ?

This worked when I replace the syncController instance with the instance I created on the APPDelegate during the initial background fetch .

I did this in my tab bar controller viewDidLoad:

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    _syncController = appDelegate.syncController;
    syncNAv = [syncNAv initWithRootViewController:_syncController];

    [vcArr removeLastObject];
    [vcArr addObject:syncNAv];

    [self setViewControllers:[vcArr copy]];

and then the values were updating properly as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM