iosswift3xcode9twitterkit

twitterKit Login completion block is never executed


I'm trying to post some content to twitter from my app, and since iOs 11 unfortunately the old way don't work anymore so I'm implementing twitterKit and finding some spikes.

When I don't have the app installed, it runs the completion block below, which is weird because I had to dismiss the alert myself manually, as the alert don't have any buttons to do it.

But my real problem is that I have the twitter app installed and I'm loggued in. But I'm unable to detect it with twitter kit. And when I press the share to twitter button, the app switch to a new view, were it asks me to connect my app to my twitter (If I'm not loggued in I have a login and password box but the result is always the same...) When I press "Connect", the view goes back to my app and nothing happens, the completion block is never called... I'm working in iOs 11 and x-code 9 but I've tried the same aproach with iOs 10 and I get the same result. Twitter login is never detected. This is the code I'm running, any help would be apreciated:

if (Twitter.sharedInstance().sessionStore.hasLoggedInUsers()) {
    // App must have at least one logged-in user to compose a Tweet
    let composer = TWTRComposerViewController.emptyComposer()
    present(composer, animated: false, completion: {
        print("This code never runs")
    })
} else {
    // Log in
    Twitter.sharedInstance().logIn { session, error in
        if session != nil {
            // Log in succeeded / Never happens
            let composer = TWTRComposerViewController.emptyComposer()
            composer.delegate = self
            self.present(composer, animated: true, completion: {
                print ("This code never runs")
            })
        } else {
            let alert = UIAlertController(title: "No Twitter Accounts Available", message: "You must log in before presenting a composer.", preferredStyle: .alert)

            //Only happens if I don't have the twitter app installed on my device
            self.present(alert, animated: false, completion: {
                print ("not loggued in")

                /*
                 manual dismission of the prompt as it don't have
                 any button
                 */
                sleep(3)
                alert.dismiss(animated: true, completion: nil)

            })
        }
    }
}

In the console I'm getting this error: [Snapshotting] Snapshotting a view (0x105977000, UIKeyboardImpl) that has not been rendered at least once requires afterScreenUpdates:YES.

EDIT: I solved it adding this method in appDelegate:

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { return Twitter.sharedInstance().application(app, open: url, options: options) }


Solution

  • As you found out, you need to let the TwitterKit to handle reopening the app when it's redirected back from twitter:

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        let twtrHandled = TWTRTwitter.sharedInstance().application(app, open: url, options: options)
        return twtrHandled
    }
    

    If you have several kits there that can handle URL, this is the way I handle it (here I use also facebook SDK, and Branch SDK):

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        let branchHandled = Branch.getInstance().application(app, open: url, options: options)
        let fbHandled = SDKApplicationDelegate.shared.application(app, open: url, options: options)
        let twtrHandled = TWTRTwitter.sharedInstance().application(app, open: url, options: options)
        return branchHandled || fbHandled || twtrHandled
    }