[GH-ISSUE #154] "Attempt to present X on Y whose view is not in the window hierarchy!" using authorize_url_handler #96

Closed
opened 2026-03-03 16:45:37 +03:00 by kerem · 10 comments
Owner

Originally created by @DennisDreissen on GitHub (Dec 8, 2015).
Original GitHub issue: https://github.com/OAuthSwift/OAuthSwift/issues/154

I'm trying to let my users authenticate from within my application, so they don't need to be redirected to safari. I have implemented the WebViewController and set the authorize_url_handler to WebViewController. But I'm getting the following warning:

Warning: Attempt to present <.WebViewController: 0x7967b7e0> on <.LoadingViewController: 0x7a029e60> whose view is not in the window hierarchy!

Am I missing something here? I can't seem to find any information about it anywhere, so that's why I'm asking here.

Originally created by @DennisDreissen on GitHub (Dec 8, 2015). Original GitHub issue: https://github.com/OAuthSwift/OAuthSwift/issues/154 I'm trying to let my users authenticate from within my application, so they don't need to be redirected to safari. I have implemented the WebViewController and set the authorize_url_handler to WebViewController. But I'm getting the following warning: Warning: Attempt to present <.WebViewController: 0x7967b7e0> on <.LoadingViewController: 0x7a029e60> whose view is not in the window hierarchy! Am I missing something here? I can't seem to find any information about it anywhere, so that's why I'm asking here.
kerem 2026-03-03 16:45:37 +03:00
Author
Owner

@phimage commented on GitHub (Dec 8, 2015):

ios?
without your code difficult to give an exact answer but the error seems clear and just do a google search on "whose view is not in the window hierarchy" if my response if wrong

did you use addChildViewController ?
If you present a view not using as parent the root, you must add the WebViewController as child controller of the parent controller view where you did presentXXX....

<!-- gh-comment-id:163001160 --> @phimage commented on GitHub (Dec 8, 2015): ios? without your code difficult to give an exact answer but the error seems clear and just do a google search on "whose view is not in the window hierarchy" if my response if wrong did you use addChildViewController ? If you present a view not using as parent the root, you must add the WebViewController as child controller of the parent controller view where you did presentXXX....
Author
Owner

@DennisDreissen commented on GitHub (Dec 8, 2015):

WebViewController: http://pastebin.com/GdA8iFFE

func authenticateUser() {
    let theView = WebViewController()
    OAuth.authorize_url_handler = theView
    OAuth.authorizeWithCallbackURL( NSURL(string: "MyApp://oauth")!, success: {
        credential, response in
        print("success")
        }, failure: { error in
            print(error)
    })
}

I have tried adding self.addChildViewController(theView) but that crashes the application with the following error: Application tried to present modally an active controller

<!-- gh-comment-id:163004628 --> @DennisDreissen commented on GitHub (Dec 8, 2015): WebViewController: http://pastebin.com/GdA8iFFE ``` func authenticateUser() { let theView = WebViewController() OAuth.authorize_url_handler = theView OAuth.authorizeWithCallbackURL( NSURL(string: "MyApp://oauth")!, success: { credential, response in print("success") }, failure: { error in print(error) }) } ``` I have tried adding self.addChildViewController(theView) but that crashes the application with the following error: Application tried to present modally an active controller
Author
Owner

@phimage commented on GitHub (Dec 8, 2015):

ok you copy demo code using the OAuthWebViewController

and the code used to present is :

 UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(
theWebViewController, animated: true, completion: nil)

I will test the demo app just in case, but I think there is not problem, I have tested also with Safari handler before committing

maybe it's because you are not displaying currently the UIApplication.sharedApplication().keyWindow?.rootViewController, but another when doing the job
I will add a function to override to choose the good controller, the one that is displayed maybe

or have you a UINavigationController? a Storyboard?

or you call authenticateUser when you have not finished to load a view (for instance in a viewDidLoad stack)
put a break point and see thread stack

<!-- gh-comment-id:163014389 --> @phimage commented on GitHub (Dec 8, 2015): ok you copy demo code using the `OAuthWebViewController` and the code used to present is : ``` swift UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController( theWebViewController, animated: true, completion: nil) ``` I will test the demo app just in case, but I think there is not problem, I have tested also with Safari handler before committing maybe it's because you are not displaying currently the `UIApplication.sharedApplication().keyWindow?.rootViewController`, but another when doing the job _I will add a function to override to choose the good controller, the one that is displayed maybe_ or have you a `UINavigationController`? a Storyboard? or you call `authenticateUser` when you have not finished to load a view (for instance in a viewDidLoad stack) put a break point and see thread stack
Author
Owner

@DennisDreissen commented on GitHub (Dec 8, 2015):

I'm calling the authenticateUser after the user presses a button, so the view has loaded. When the app loads it loads a view calling LoadingViewController, if the user is not logged in it shows the LoginViewController, which contains the button and the authenticateUser method.

Not sure what to do now?

<!-- gh-comment-id:163015461 --> @DennisDreissen commented on GitHub (Dec 8, 2015): I'm calling the authenticateUser after the user presses a button, so the view has loaded. When the app loads it loads a view calling LoadingViewController, if the user is not logged in it shows the LoginViewController, which contains the button and the authenticateUser method. Not sure what to do now?
Author
Owner

@phimage commented on GitHub (Dec 8, 2015):

try in WebViewController, override func handle(url: NSURL) {
do not call super.handle(url:)

instead do some code to present the view from your LoadingViewController
loadingViewConroller.presentViewController(self, animated: true, completion: nil)

you can add this LoadingViewController into your WebViewController as attribute when you creating it (passing in init for instance)

<!-- gh-comment-id:163016731 --> @phimage commented on GitHub (Dec 8, 2015): try in WebViewController, override func handle(url: NSURL) { do not call super.handle(url:) instead do some code to present the view from your LoadingViewController loadingViewConroller.presentViewController(self, animated: true, completion: nil) you can add this LoadingViewController into your WebViewController as attribute when you creating it (passing in init for instance)
Author
Owner

@DennisDreissen commented on GitHub (Dec 8, 2015):

Alright, got it working now. Would be awesome to be able to override the controller, so I can pass the LoginViewController to the handle method.

Thanks for helping! 👍

<!-- gh-comment-id:163018227 --> @DennisDreissen commented on GitHub (Dec 8, 2015): Alright, got it working now. Would be awesome to be able to override the controller, so I can pass the LoginViewController to the handle method. Thanks for helping! :+1:
Author
Owner

@phimage commented on GitHub (Dec 8, 2015):

yes I will add that to OAuthWebViewController
or manage child/parent relation in controller like in OSX to choose the controller which present

and keep the issue open until that

<!-- gh-comment-id:163018933 --> @phimage commented on GitHub (Dec 8, 2015): yes I will add that to OAuthWebViewController or manage child/parent relation in controller like in OSX to choose the controller which present and keep the issue open until that
Author
Owner

@phimage commented on GitHub (Dec 9, 2015):

maybe I don't understand the question.
You put a UIWebView into your custom WebViewController (by coping demo code) that's the way to do it.

PS: there is also Join the chat at https://gitter.im/dongri/OAuthSwift to ask little question

<!-- gh-comment-id:163137550 --> @phimage commented on GitHub (Dec 9, 2015): maybe I don't understand the question. You put a UIWebView into your custom WebViewController (by coping demo code) that's the way to do it. PS: there is also [![Join the chat at https://gitter.im/dongri/OAuthSwift](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dongri/OAuthSwift?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) to ask little question
Author
Owner

@driver733 commented on GitHub (Dec 10, 2015):

If anyone is interested, here is how I managed to solve the discussed problem.

public func handle(url: NSURL){
        #if os(iOS)
           var topController = UIApplication.sharedApplication().keyWindow?.rootViewController      
           while ((topController?.presentedViewController) != nil) {
            topController = topController?.presentedViewController
           }
          topController?.presentViewController(self, animated: true, completion: nil)
       ...
<!-- gh-comment-id:163754607 --> @driver733 commented on GitHub (Dec 10, 2015): If anyone is interested, here is how I managed to solve the discussed problem. ``` public func handle(url: NSURL){ #if os(iOS) var topController = UIApplication.sharedApplication().keyWindow?.rootViewController while ((topController?.presentedViewController) != nil) { topController = topController?.presentedViewController } topController?.presentViewController(self, animated: true, completion: nil) ... ```
Author
Owner

@phimage commented on GitHub (Dec 11, 2015):

97d692c198 @driver733 I take your code but make a recursive one in UIViewController/UIApplication extension
I make special case for UINavigationController and UITabViewController as I read on internet but maybe I do wrong by doing this

@driver733 @DennisDreissen feedback is welcome because I have no app with a controller hierarchy to test (demo app have only an UINavigationController as root)

<!-- gh-comment-id:163901678 --> @phimage commented on GitHub (Dec 11, 2015): 97d692c198918a14483dca7460ec193957662641 @driver733 I take your code but make a recursive one in `UIViewController`/`UIApplication` extension I make special case for `UINavigationController` and `UITabViewController` as I read on internet but maybe I do wrong by doing this @driver733 @DennisDreissen feedback is welcome because I have no app with a controller hierarchy to test (demo app have only an `UINavigationController` as root)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/OAuthSwift#96
No description provided.