Please don't mark this as duplicate. I have tried every other related post and they didn't work for me. I have looked at countless examples (StackOverflow/MBProgressHUD Demo/etc.) trying to get this to work. I feel like most examples are outdated as some methods are deprecated. This is the closest I have got.
The MBProgress HUD should display the default loading screen with "Preparing" before I start connecting to JSON. When I connect, I want the mode to change to AnnularDeterminate when I receive a response. Once it's finished loading, I want the progress bar to display my progress of adding the data to a dictionary. Once that is done, change the mode to CustomView displaying a checkmark image and "Completed".
The MBProgress HUD will display. However, it only shows the default loading screen with "Preparing..." underneath it and then it will say "Completed" with the checkmark custom view after progress is at 1.0. There is no Determinate view with my updated progress in between.
- (void)viewDidLoad
{
buildingsDataArray = [[NSMutableArray alloc] init];
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.delegate = self;
HUD.label.text = NSLocalizedString(@"Preparing...", @"HUD preparing title");
[self connect];
NSLog(@"End of setup");
}
- (void)connect
{
NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:buildingList]];
connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
NSLog(@"End of connect");
}
// Connection delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"connection received response");
[MBProgressHUD HUDForView:self.view].mode = MBProgressHUDModeAnnularDeterminate;
NSLog(@"Changed mode");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
NSLog(@"connection received data");
[MBProgressHUD HUDForView:self.view].progress = 0.0f;
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"Fail with error - %@ %@", [error localizedDescription], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
if ([[error localizedDescription] isEqualToString:@"The Internet connection appears to be offline."]) {
//do something
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSArray *allDataArray = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];
float count = [allDataArray count];
float c=1;
if ([buildingsDataArray count]!=0)
[buildingsDataArray removeAllObjects];
for (NSDictionary *dataDict in allDataArray){ //from 1 to 6
if ([[dataDict objectForKeyedSubscript:@"id"] intValue] != 0)
[buildingsDataArray addObject:dataDict];
usleep(200000);
float p = c/count;
[MBProgressHUD HUDForView:self.view].progress = p;
NSLog(@"Progress: %f", [MBProgressHUD HUDForView:self.view].progress);
});
c++;
}
[MBProgressHUD HUDForView:self.view].customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Checkmark.png"]];
[MBProgressHUD HUDForView:self.view].label.text = NSLocalizedString(@"Completed", @"HUD done title");
[MBProgressHUD HUDForView:self.view].mode = MBProgressHUDModeCustomView;
[[MBProgressHUD HUDForView:self.view] hideAnimated:YES afterDelay:1.0f];
}
And here is my console output
End of connect
End of setup
connection received response
Changed mode
connection received data
connection finished loading
Progress: 0.166667
Progress: 0.333333
Progress: 0.500000
Progress: 0.666667
Progress: 0.833333
Progress: 1.000000
When I try adding
dispatch_async(dispatch_get_main_queue()
outside all of the MBProgress method calls inside my connection delegate, I get the default loading screen again. But after progress reaches 1.0, the determinate loading screen view shows (fully loaded) with "Completed" and then disappears after delay 1.0. There is still no loading process in between. Also, the checkmark image never shows. I don't think this is the way to do it.
The output when I do this is:
End of connect
End of doSetup
connection received response
connection received data
connection finished loading
Changed mode
Progress: 0.166667
Progress: 0.333333
Progress: 0.500000
Progress: 0.666667
Progress: 0.833333
Progress: 1.000000
Here is a useful reference that touches base on UICalls on different threads: Is there a way to make drawRect work right NOW?
This is what worked:
NSURLConnection was being called on the main thread. So all of my UI updates weren't occurring until after the connection delegate calls were finished.
So to fix this problem, I put the connection in a background thread.
- (void)viewDidLoad{
//...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
NSURL *URL = [NSURL URLWithString:buildingList];
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:URL];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection setDelegateQueue:[[NSOperationQueue alloc] init]];
[connection start];
});
}
Inside the connection delegate methods, I surrounded each MBProgress call with
dispatch_async(dispatch_get_main_queue(), ^{
//...
}
Hope this helps others. I spent all day on this and it was such a simple misunderstanding...