The main UI is not updated when using async calls (or block)

With the last DA SDK for XCode.

I try to update a progress bar (using https://github.com/jdg/MBProgressHUD). The weird thing I found is that my calls to the UI are ignored until all the block is executed.

I’m downloading a list of giles. Lets say are 10. When the 10 files finish to download, the UI start to process (delayed) the updates. MBProgressHUD correctly do their stuff if is called in a background thread (However, I found this is call in the main thread).

I change it to use asyncrequest + delegate with the same result. I change the MBProgressHUD with UIAlertView and the screen dim but the alertview is not show at all (as if tit was behind the windows).

So, how do this kind of task?

HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
[self.navigationController.view addSubview:HUD];

HUD.delegate = self;
HUD.labelText = @"Sincronizando imagenes...";

[HUD show:YES];

NSDate *lastSync = [NSDate dateFromISOString:@"2012-01-01"];

[[BestSellerCloud server].srvData beginPhoto_download_list:lastSync startWithBlock:^(ROAsyncRequest *r)
 {
     
     HUD.mode = MBProgressHUDModeDeterminate; <= Don't happend instantly

     // Download and write to file
     for (NSString* file in files) {
         if ([file length] == 0) {
             continue;
         }
         
         localPath = [file lastPathComponent];
         
         ALog(@"Descargando %@", file);
         HUD.labelText = [NSString stringWithFormat:@"Descargando %@", localPath];   <= Don't happend instantly             
         
         count++;
         
         HUD.progress = ((count * 100.0) / [files count] / 100.0); <= Don't happend instantly
     }

     [HUD hide:YES afterDelay:2];
 }];    

Hi,

Yeah, this happens because the code in your block section will be executed at the end of the asynchronous method call.

Actually startWithBlock means “Start this method in the background thread and if it completes successfully then execute my code in the block”.

You can try to use
asyncRequest:didReceiveDataSize:ofExpected:
delegate method of the async request and from there drive the progress of your HUD window

I don’t understand… the code that I’m executing is all in the block. It process the files that get from the async call at the end, then show the progress of them all in the block. I’m not talking about the progress of the call to the DA server, but the progress of the process of the result from that call (in pseudocode)

GetDataFromDA:
Block(
FileList = AsyncRequest.Result…
for file in FileList:
ShowProgress
)

ah ok,

but in this case your MBProgressHUD and the code in block, that increases progress, runs in the same main thread. So HUD have no chances to update itself until block ends.

You can try to refactor the code from block into separate method and then call
showWhileExecuting:onTarget:withObject:animated method of the MBProgressHUD.

something like following:


-(void)myProgressTask:(NSArray *)FileList {
    for file in FileList:
        ShowProgress
}

[service beginMehtod:... startWithBlock:^(ROAsyncRequest *r) {
    NSArray *res = [r endMethod...];
    HUD = [[MBProgressHUD alloc] init...];
    //configure it and show
    [HUD showWhileExecuting:@selector(myProgressTask) 
                   onTarget:self 
                 withObject:res 
                   animated:YES];
	
}

ops, sorry small mistype in the pseudocode above, selector for method with parameter should be @selector(myProgressTask:)