1

The app interacts with php scripts on my server. A user can create a booking, and details are written to a database. Subsequently, they can cancel that booking.

Within the app, a booking is an object, responsible for gathering its own details from the server. A booking can also cancel itself (at the user's request) - pressing "the cancel button" in BookingViewController calls the booking's (void)cancelBooking method, which posts to bookings-cancel.php using an NSURLSessionUploadTask with json data rolled from @{ @"invoiceNumber": self.invoiceNumber }.

The database is updated, the uploadSession returns new details, and the booking updates itself according. All of this is nicely responsive - up and back in less than a second, consistently.

The problem comes when I attempt to update the UI on BookingViewController (labels for delivery date and price) using values read from the booking object after it has updated itself (within the uploadSession completion block).

BookingViewController is assigned as the booking's delegate. The booking is setup for KVO on its own "price" property. Whenever the price changes, the booking calls a delegate method priceDidChange:(NSString *)updatedPrice on BookingViewController, triggering an NSLog and updates to deliveryLabel.text and priceLabel.text.

- (void)priceDidUpdate:(NSString *)updatedPrice {
    NSLog(@"priceDidUpdate delegate notification - updatedPrice is: %@", updatedPrice);
    [self.deliveryLabel setText:@"N/A"];
    [self.priceLabel setText:updatedPrice];
}

Testing has shown that if I update the price directly from the "cancel" button, or with any other explicit command (e.g., self.price = @"123.45") within the cancelBooking method outside of the uploadTask, then the UI updates just as quickly as the NSLog is written out (i.e., near instantaneously).

However, if the price is updated within the uploadTask completion block, the NSLog will write out just as responsively but the updates to deliveryLabel.text and priceLabel.text are very slow to occur - the delay varies between 5 and 12 seconds, approximately.

I've got NSLogs all over the place, and am confident this is not merely about a delay getting the updated value to or from the booking object. Easily twenty times already I have seen "priceDidUpdate delegate notification - updatedPrice is: 0.00" (the updated price), then counted to 10 before self.priceLabel.text is actually set to @"0.00". Totally stumped.

In case it matters, the NSURLSession is configured using ephemeralSessionConfiguration with no adjustments.

Is there any reason why the UI updates in BookingViewController should take longer to occur based on whether or not the call to priceDidChange comes from inside or outside the uploadTask completion block?

Thanks in advance!

Nirav Gadhiya
  • 6,342
  • 2
  • 37
  • 76
goNats12
  • 13
  • 3
  • Make sure you're updating the UI on the MAIN THREAD... – Shai Jun 09 '15 at 12:59
  • Thanks, Shai. I'd looked into that, and mucked about with a couple GCD tutorials, but... the UI updates are always triggered from within priceDidChange - the only difference is where priceDidChange is being called from: inside or outside the uploadTask completion block. Am I wrong to believe this should rule out which thread is being used to call the UI updates? – goNats12 Jun 09 '15 at 13:07
  • without diving into your code or trying to understand what you're trying to do or even trying to figure what code executes where - this can be easily solved by wrapping your label updates inside a dispatch_a/sync block that runs on the main queue... – Shai Jun 09 '15 at 13:09

1 Answers1

3

Use main queue to update the UI. Use following code:

- (void)priceDidUpdate:(NSString *)updatedPrice 
{
    dispatch_async(dispatch_get_main_queue(), ^()
    {
            //Add method, task you want perform on mainQueue
            //Control UIView, IBOutlet all here
            NSLog(@"priceDidUpdate delegate notification - updatedPrice is: %@", updatedPrice);
            [self.deliveryLabel setText:@"N/A"];
            [self.priceLabel setText:updatedPrice];
    });
}
Nirav Gadhiya
  • 6,342
  • 2
  • 37
  • 76
  • Thank you, N J! Worked like a charm. In my struggles I had indeed wound up digging into GCD, but it was just too foreign - the answer looks like something I tried, except that it actually works! :-) FWIW, I'm a first-time caller, long-time listener. SO FTW. Thanks, again! – goNats12 Jun 09 '15 at 20:50