Hey,
I’m experiencing an issue where i’m using the TwitterKit SDK to sign in via the .WebBased or .WebBasedForceLogin methods however when the logInWithViewController(viewController: UIViewController?, methods: TWTRLoginMethod, completion: TWTRLogInCompletion) method completes, it seems to dismiss my own view controllers that are presented too.
I’m using TwitterKit 2.2.0 installed via Cocoapods (no fabric stuff).
Here is the view controller hierarchy prior to interacting with the TwitterSDK for login:
(lldb) expr -l objc++ -O -- [[[UIWindow keyWindow] rootViewController] _printHierarchy]
<RedactedTabBarController 0x7a9bb600>
| <UINavigationController 0x7a9ed400>
| | <RedactedViewController 0x7a9e3200>
+ <RedactedLoginNavigationController 0x7b96d800>
| | <Redacted.LoginMethodSelectionViewController 0x7c061500>
I then call the following from within LoginMethodSelectionViewController:
Twitter.sharedInstance().logInWithViewController(self, methods: .WebBased) { session, error in
}
Then, by the time the callback completes, both the SFSafariViewController and my presented RedactedLoginNavigationController are dismissed however this is not desired.
I put a symbolic breakpoint on [UIViewController dismissViewControllerAnimated:completion:] to try and work out why both view controllers were being dismissed and it looks like the SDK calls this method on two separate occasions:
The first time looks to be a result of me calling -[Twitter application:openURL:options:] from my UIApplicationDelegete, it looks like this is what dismisses the SFSafariViewController and it’s called prior to the callback… Here is the stack trace:
(lldb) bt
* thread #1: tid = 0x1235167, 0x03759142 UIKit`-[UIViewController dismissViewControllerAnimated:completion:], queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
* frame #0: 0x03759142 UIKit`-[UIViewController dismissViewControllerAnimated:completion:]
frame #1: 0x004eda5b RedactedApp`__68-[TWTRWebAuthenticationFlow presentWebAuthenticationViewController:]_block_invoke.64 + 55
frame #2: 0x004ed472 RedactedApp`-[TWTRWebAuthenticationFlow resumeAuthenticationWithRedirectURL:] + 181
frame #3: 0x005226e7 RedactedApp`-[Twitter application:openURL:options:] + 81
frame #4: 0x0024de45 RedactedApp`-[AppDelegate application:openURL:options:](self=0x7a774040, _cmd="application:openURL:options:", app=0x7a66d3f0, url=@"twitterkit-zloflngcluv2m5snzxr6neghs://callback?app=ZLoFLNGCLUv2m5SNZxr6NEgHs&oauth_token=T5BFRwAAAAAAvM8TAAABVUE4JnA&oauth_verifier=CLMbokmg645Uy0JrAHGe2SNAerr903WC", options=2 key/value pairs) + 213 at AppDelegate.m:441
frame #5: 0x03578aa4 UIKit`__45-[UIApplication _applicationOpenURL:payload:]_block_invoke + 983
frame #6: 0x0357846f UIKit`-[UIApplication _applicationOpenURL:payload:] + 787
frame #7: 0x03589633 UIKit`-[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:] + 5408
frame #8: 0x0358f92f UIKit`__88-[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:]_block_invoke + 238
frame #9: 0x0358f7d9 UIKit`-[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:] + 469
frame #10: 0x0356a067 UIKit`__70-[UIApplication scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke + 197
frame #11: 0x03569c57 UIKit`-[UIApplication scene:didUpdateWithDiff:transitionContext:completion:] + 770
frame #12: 0x08735177 FrontBoardServices`__80-[FBSSceneImpl updater:didUpdateSettings:withDiff:transitionContext:completion:]_block_invoke_2 + 71
frame #13: 0x08734aae FrontBoardServices`__40-[FBSSceneImpl _performDelegateCallOut:]_block_invoke + 54
frame #14: 0x0875827f FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 23
frame #15: 0x087580ab FrontBoardServices`-[FBSSerialQueue _performNext] + 174
frame #16: 0x087584fa FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 52
frame #17: 0x087577e8 FrontBoardServices`FBSSerialQueueRunLoopSourceHandler + 33
frame #18: 0x05be8e5f CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
frame #19: 0x05bdeaeb CoreFoundation`__CFRunLoopDoSources0 + 523
frame #20: 0x05bddf08 CoreFoundation`__CFRunLoopRun + 1032
frame #21: 0x05bdd846 CoreFoundation`CFRunLoopRunSpecific + 470
frame #22: 0x05bdd65b CoreFoundation`CFRunLoopRunInMode + 123
frame #23: 0x0913d664 GraphicsServices`GSEventRunModal + 192
frame #24: 0x0913d4a1 GraphicsServices`GSEventRun + 104
frame #25: 0x0356ceb9 UIKit`UIApplicationMain + 160
frame #26: 0x00169c0a RedactedApp`main(argc=1, argv=0xbff9a8a8) + 138 at main.m:16
frame #27: 0x06adfa25 libdyld.dylib`start + 1
The second time is actually called after the login callback is executed but I don’t think it should be? Anyway, here is the stack trace:
(lldb) bt
* thread #1: tid = 0x1235167, 0x03759142 UIKit`-[UIViewController dismissViewControllerAnimated:completion:], queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
* frame #0: 0x03759142 UIKit`-[UIViewController dismissViewControllerAnimated:completion:]
frame #1: 0x0052258e RedactedApp`__56-[Twitter performWebBasedLogin:forcingLogin:completion:]_block_invoke.269 + 81
frame #2: 0x004edcd3 RedactedApp`-[TWTRWebAuthenticationFlow succeedWithSession:] + 114
frame #3: 0x004edb91 RedactedApp`__41-[TWTRWebAuthenticationFlow saveSession:]_block_invoke + 71
frame #4: 0x004bdfe8 RedactedApp`__60-[TWTRSessionStore saveSession:withVerification:completion:]_block_invoke_2 + 25
frame #5: 0x02feaef2 ReactiveCocoa`__RACBacktraceBlock_block_invoke(.block_descriptor=0x7c6a4270) + 98 at RACBacktrace.m:67
frame #6: 0x06a91363 libdispatch.dylib`_dispatch_call_block_and_release + 15
frame #7: 0x06ab49cd libdispatch.dylib`_dispatch_client_callout + 14
frame #8: 0x06a99f7c libdispatch.dylib`_dispatch_main_queue_callback_4CF + 910
frame #9: 0x05c201be CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
frame #10: 0x05bde434 CoreFoundation`__CFRunLoopRun + 2356
frame #11: 0x05bdd846 CoreFoundation`CFRunLoopRunSpecific + 470
frame #12: 0x05bdd65b CoreFoundation`CFRunLoopRunInMode + 123
frame #13: 0x0913d664 GraphicsServices`GSEventRunModal + 192
frame #14: 0x0913d4a1 GraphicsServices`GSEventRun + 104
frame #15: 0x0356ceb9 UIKit`UIApplicationMain + 160
frame #16: 0x00169c0a RedactedApp`main(argc=1, argv=0xbff9a8a8) + 138 at main.m:16
frame #17: 0x06adfa25 libdyld.dylib`start + 1
I can’t find anything in the documentation to handle this scenario so it would be great if you could help me out.
Update: looks like this only happens in iOS 9 where SFSafariViewController is used. I assume this is because both the AppDelegate callback handling is dismissing the view controller and so is the logic within -[Twitter performWebBasedLogin:forcingLogin:completion:] where it is not required if SFSafariViewController is used.
Update2: rolling back to 2.1.1 fixes this issue as it doesn’t contain SFSafariViewController support.
Thanks,
Liam