Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Photo Browser iPhone App Connecting to an API using OAuth Introducing API and OAuth 2.0

Sri Kadimisetty
Sri Kadimisetty
9,770 Points

Not able to see SimpleAuth screen because of "Warning: Attempt to present <NavigationController> on .<NavigationCont …

So when I place this piece of code in view-did-load

[SimpleAuth authorize:@"instagram"
completion:^(id responseObject, NSError *error) {
                       NSLog(@"reponse: %@", responseObject)
}];

and try to run, I get this error that prevent me to get that token mentioned in the video

2014-04-01 03:39:14.335 Photo Bombers[35182:60b] Warning: Attempt to present <UINavigationController: 0x8f786a0> on <UINavigationController: 0xcf68770> whose view is not in the window hierarchy!

A bit of googling brings me to a stack overflow post that mentions it might be because the view was not drawn yet -

Don't do this in viewDidLoad, your view isn't on screen yet, so that's why you get that error. You should do it in viewDidAppear (with no animation if you don't want to see the view of the controller that this code is in).

Moving that SimpleAuth code to viewDidAppear does not raise the error but makes the modal window keep popping up multiple times , BUT it does print the token to the console.

To be fair, The stackoverflow post comments does warn about this, and mentions something about doing a check to make the task only complete once. I placed a property Bool to check if the code has run and placed it in viewdidappear behind that check, but then it just gives up and i get that view is not in the window hierarchy error again.

PS - I really hope this made sense.

4 Answers

Misha Shaposhnikov
Misha Shaposhnikov
8,718 Points

I found the solution to the error. Go to the AppDelegate.m and go to the didFinishLaunchingWithOptions function. Remove the line that calls the authorize class method on SimpleAuth. It should look like this:

[SimpleAuth authorize:@"instagram" completion:^(id responseObject, NSError *error) {
    }];

What's happening was that this call was being made in the app delegate, so Simple Auth pushed their UINavigationController onto of the root view controller of the window, which was the UINavigationController that we initialized with our custom class PhotosViewController as the root view controller in these lines:

THPhotosViewController *photosViewController = [[THPhotosViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:photosViewController];

Then, that same call was made again in the viewDidLoad method of the PhotosViewController.

    if (self.accessToken == nil) {
        [SimpleAuth authorize:@"instagram" completion:^(NSDictionary *responseObject, NSError *error) {

   //Other code omitted for spacing purposes

Really the call to authorize should only be called once anyway, and Xcode was freaking out that there was a dynamically initialized UINavigationController onto of another dynamically initialized UINavigationController onto of our originally initialized UINavigationController.

Hope this helps, and tell me if it does. =)

Robert Bojor
PLUS
Robert Bojor
Courses Plus Student 29,439 Points

Hi there,

Had the same problem with this. Managed to move it to viewDidAppear and it works once you use it in tandem with a BOOL. Here's my code:

//PhotosViewController.h
@property (nonatomic) BOOL didAuth;

//PhotosViewController.m
-(void)viewDidLoad {
    [super viewDidLoad];
    [self.collectionView registerClass:[PhotoCell class] forCellWithReuseIdentifier:@"photo"];
    self.collectionView.backgroundColor = [UIColor whiteColor];
    self.title = @"Photo Bombers";
    self.didAuth = NO;
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (!self.didAuth) {
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        self.accessToken = [userDefaults objectForKey:@"accessToken"];
        if (self.accessToken == nil) {
            [SimpleAuth authorize:@"instagram" completion:^(id responseObject, NSError *error) {
                NSLog(@"%@", responseObject);
                self.accessToken = responseObject[@"credentials"][@"token"];
                [userDefaults setObject:self.accessToken forKey:@"accessToken"];
                [userDefaults synchronize];
            }];
        } else {
            NSLog(@"Signed in!");
        }
        self.didAuth = YES;
    }
}
Robert Bojor
Robert Bojor
Courses Plus Student 29,439 Points

Forgot to mention it doesn't pop the Instagram modal, it brings it up and down again since I've already logged in.

Robert Bojor
Robert Bojor
Courses Plus Student 29,439 Points

Well, I came back to the app after a while and now is doing the same thing again as before, even with the code moved in the ViewDidAppear.

Sri, did you manage to fix it in the end?

Chris Stanely
Chris Stanely
2,325 Points

I too am having the same issue. I've used the code above but still getting the error, has anyone managed to fix this?

PhotoBombers[776:60b] Warning: Attempt to present <UINavigationController: 0x17dc2220> on <UINavigationController: 0x17dada50> whose view is not in the window hierarchy!

Robert Bojor
PLUS
Robert Bojor
Courses Plus Student 29,439 Points

A new thing we might try, and I say might since I'm not in front of my computer right now, is [self performSelector:withObject:afterDelay:] in the viewDidLoad and pass it like 0.5 for the delay, or even less, and see what's happening.

Will try if no one else does later on and come back with comments.