Our iPad app uses a UINavigationController in a UIPopoverController.
The second view managed by the navigation controller is a subclass of UITableViewController, which when the correct row is chosen, pushes a GDataOAuthViewControllerTouch, as described on http://code.google.com/p/gdata-objectivec-client/wiki/OAuthSignInControllers :

GDataOAuthViewControllerTouch *googleOAuthViewController =
[[GDataOAuthViewControllerTouch alloc] initWithScope:@"http://www.google.com/reader/api/*"
                                            language:nil
                                      appServiceName:kAppServiceName
                                            delegate:self
                                    finishedSelector:@selector(viewController:finishedWithAuth:error:)];

googleOAuthViewController.contentSizeForViewInPopover = CGSizeMake(400.0, 577.0);
googleOAuthViewController.navigationItem.title = @"Google Account";

[self.navigationController pushViewController:googleOAuthViewController animated:YES];
[googleOAuthViewController release];

The finished method is called with success:

- (void)viewController:(GDataOAuthViewControllerTouch *)viewController
      finishedWithAuth:(GDataOAuthAuthentication *)auth
                 error:(NSError *)error {
    // error == nil
}

Yet, when the app then tries to retrieve the subscription list, the request somehow gets cancelled:

Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn\u2019t be completed.

Code -1012 is kCFURLErrorUserCancelledAuthentication = -1012 (defined in CFNetworkErrors.h).

When googleOAuthViewController is presented as a modal controller instead:

[self presentModalViewController:googleOAuthViewController animated:YES];

then the requested data is retrieved without problem.

It is not clear what causes the request to be cancelled when the controller is pushed onto the navigation controller and how to fix this.

1

There are 1 answers

0
attt On BEST ANSWER

Our app synchronously requests a user's subscription list from Google Reader.

The problem mentioned occurs when googleOAuthViewController is on the stack of a UINavigationController and is not the root controller. Google's code pops the controller in the popView method in GDataOAuthViewControllerTouch.m (lines 361-375 in gdata-objectivec-client-1.11.0) when it's done. Somehow the call of popViewControllerAnimated interferes with the request, executed in the callback (on successful authentication):

- (void)viewController:(GDataOAuthViewControllerTouch *)viewController
      finishedWithAuth:(GDataOAuthAuthentication *)auth
                 error:(NSError *)error

If lines 367 through 370 in GDataOAuthViewControllerTouch.m are commented out:

//      isPoppingSelf_ = YES;

//      [[self navigationController] popViewControllerAnimated:YES];
//      [[self view] setHidden:YES];

then the request always succeeds. Google's view must then be popped in the app, AFTER the request has completed.