4

I am sure this is an issue with my iOS/ObjC noob-ness...

I have a UITableView with entries in, when the user selects a row,

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
...
   [self.twitter sendUpdate:[self getTweet]];

and

- (NSString *)sendUpdate:(NSString *)text;
{
    NSLog(@"showing HUD");
    self.progressSheet = [MBProgressHUD showHUDAddedTo:[[UIApplication sharedApplication] keyWindow] animated:YES];
    self.progressSheet.labelText = @"Working:";
    self.progressSheet.detailsLabelText = text;

    // Build a twitter request
    TWRequest *postRequest = [[TWRequest alloc] initWithURL:
                              [NSURL URLWithString:@"http://api.twitter.com/1/statuses/update.json"] 
                                                 parameters:[NSDictionary dictionaryWithObject:text 
                                                                                        forKey:@"status"] requestMethod:TWRequestMethodPOST];

    // Post the request
    [postRequest setAccount:self.twitterAccount];

    // Block handler to manage the response
    [postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) 
     {
         NSLog(@"Twitter response, HTTP response: %i", [urlResponse statusCode]);

           NSLog(@"hiding HUD");
           [MBProgressHUD hideHUDForView:[[UIApplication sharedApplication] keyWindow] animated:YES];
           self.progressSheet = nil;

It calls the builtin Twitter api to send a tweet. I am using MBProgressHUD while the sending is going on. I am getting erratic behaviour with the HUD disappearance, generally it hangs around 10 or so seconds longer than it should. Based on the show/hide logging I am seeing.

I have another, simpler view, which just lists tweets and that uses the HUD with no problem - although its done via the viewWillAppear call.

Perhaps I need to do the showing via another thread?

Thanks in advance for any thoughts ~chris

Chris Kimpton
  • 5,546
  • 6
  • 45
  • 72
  • 1
    Why attach your HUD to the window? Makes more sense to attach it to your view. Also, then instead of using hideHUDforView method why not just call hide:animated on your propertySheet HUD that you already have a reference to? That makes help. – peterept Feb 11 '12 at 12:06
  • Thanks - as its in some common code, I was avoiding passing the view around. I had tried that, but did not help. Just tried switching to using the hide: call, but no better either. I am doing some GC calls later in the didSelectRow call, but adding some logging shows thats not the hold up. – Chris Kimpton Feb 11 '12 at 17:17

3 Answers3

11

Yes, you are right about ui thread. You can also write this:

dispatch_async(dispatch_get_main_queue(), ^{
  [self.progressSheet hide:YES];
  self.progressSheet = nil;
});
Stan
  • 4,169
  • 2
  • 31
  • 39
6

It seems my issue is that I was trying to close the HUD on a thread other than the main one.

Using the trick in one of the answers to this question, its now working a lot better.

GCD to perform task in main thread

Namely, using the method defined "runOnMainQueueWithoutDeadlocking"

The close dialog code is now like this:

runOnMainQueueWithoutDeadlocking(^{
    NSLog(@"hiding HUD/mainthread");
    [self.progressSheet hide:YES];
    self.progressSheet = nil;
});
Community
  • 1
  • 1
Chris Kimpton
  • 5,546
  • 6
  • 45
  • 72
3

Try this method for showing the HUD:

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Working";

Instead of:

self.progressSheet = [MBProgressHUD showHUDAddedTo:[[UIApplication sharedApplication] keyWindow] animated:YES];
self.progressSheet.labelText = @"Working:";
self.progressSheet.detailsLabelText = text;

And this for hiding it:

[MBProgressHUD hideHUDForView:self.view animated:YES];

Instead of:

[MBProgressHUD hideHUDForView:[[UIApplication sharedApplication] keyWindow] animated:YES];
LJ Wilson
  • 14,445
  • 5
  • 38
  • 62
  • 1
    Thanks, but I had tried that unsuccessfully. I seem to have fixed it by hiding the HUD on the "main thread" - see my answer below. – Chris Kimpton Feb 11 '12 at 23:02