There are two approaches to doing this without using a custom URL Scheme, each with positives and negatives:
- Universal Links - PROS: Redirects to Safari so you don't have to build in a web browser yourself. Safari redirect also allows for using the users iCloud keychain which can make the login experience easier for your user. CONS: Setting it up is kind of a bear, and requires your own server and a published app. Doesn't seem to work in simulator.
- Setup and present a UIWebView, and in
webView:shouldStartLoadWithRequest:navigationType: catch the access token from the fragment, and prevent loading / redirection. This allows you to use any URL you want as the redirect URL because it doesn't matter :)
Example:
import UIKit
class OAuthVC : UIViewController, UIWebViewDelegate {
@IBOutlet var webView : UIWebView?
public var success : ((URLRequest) -> Void)?
public var presentVC : UIViewController?
func handle(_ url: URL) {
view.tag = 1 // Make sure our view and thus webview is loaded.
webView!.loadRequest(URLRequest(url: url))
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if request.url?.fragment?.contains("access_token") == true {
success!(request)
dismiss(animated: true, completion: nil)
return false
}
return true
}
func webViewDidFinishLoad(_ webView: UIWebView) {
// If we stop on a page before the redirect closes us, user interaction is required. Present.
presentVC?.present(self, animated: true, completion: nil)
}
}
List item