Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attempting to load the view of a view controller while it is deallocating <SFAuthenticationViewController>

Getting quite a weird bug, trying to use some very simple code.

import SafariService

class ViewController: UIViewController{
    ///All my stuff

    @IBAction func connectToReddit(){
        let authURL = URL(string: "https://www.reddit.com/api/v1/authorize?client_id=myID&response_type=code&state=myState&redirect_uri=myRedirectURI&duration=permanent&scope=myscopes")

        let scheme = "redditwatch://"
        let authSession = SFAuthenticationSession(url: authURL!, callbackURLScheme: scheme, completionHandler: { (url, error) in
            print(url?.absoluteString)
            print(error?.localizedDescription)

        })

        authSession.start()

    }
}

It is to my understanding that authSession.start() presents the user with a UIAlertController, which with my code, it does do, but the controller disappears moments after, with the error

[Warning] Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<SFAuthenticationViewController: 0x7fc1c201f600>)

You'd think creating this auth flow would be simpler, but apparently not.

Appreciate any input, thanks

like image 713
Will Avatar asked Jan 03 '18 11:01

Will


1 Answers

You need to keep a reference to the SFAuthenticationSession at the top-level. This should correct the issue:

import SafariService

class ViewController: UIViewController{
    var authSession: SFAuthenticationSession?

    ///All my stuff
    @IBAction func connectToReddit(){
        let authURL = URL(string: "https://www.reddit.com/api/v1/authorize?client_id=myID&response_type=code&state=myState&redirect_uri=myRedirectURI&duration=permanent&scope=myscopes")

        let scheme = "redditwatch://"
        authSession = SFAuthenticationSession(url: authURL!, callbackURLScheme: scheme, completionHandler: { (url, error) in
            print(url?.absoluteString)
            print(error?.localizedDescription)
        })

        authSession?.start()
    }
}

Credit for this fix to this Medium post: https://medium.com/the-traveled-ios-developers-guide/ios-11-privacy-and-single-sign-on-6291687a2ccc I could not find a reference to the scope issue in the official documentation.

Edit: The official documentation now states "Ensure that there is a strong reference to the SFAuthenticationSession instance when the session is in progress." This seems to indicate the need to move the session up in scope. This is due to the behavior that occurs when the SFAuthenticationSession initializer displays the consent dialog.

Edit2: SFAuthenticationSession was deprecated in iOS 12 and replaced with ASWebAuthenticationSession. However, ASWebAuthenticationSession has the same scope requirement. This blog has a good description of how to convert.

like image 186
Stephen Avatar answered Oct 17 '22 00:10

Stephen