我正在尝试使用OAuth2通过Spotify API对iOS应用进行身份验证。 为此,我正在使用OAuthSwift。
加载我的应用程序后,我将重定向到Spotify,我可以登录并允许我的应用程序访问我的帐户。
但是,当我重定向回我的应用程序时,WebView
被关闭了,但是立即在前一页上重新打开,关闭了它并重新打开。
这将无限期地继续循环。
我想知道这是否与在initAuthFlow
中调用我的viewDidAppear
函数有关,但是将其移至viewDidLoad
会引起抱怨
Warning: Attempt to present <OAuthKeyChainApp.WKWebViewController: 0x7fb42b505160> on <OAuthKeyChainApp.HomeController: 0x7fb42b50cf30> whose view is not in the window hierarchy!
并且永远不会显示控制器。
HomeController.swift
class HomeController: OAuthViewController {
let oauthSwift = OAuth2Swift(
consumerKey: "xxxxxx",
consumerSecret: "xxxxxx",
authorizeUrl: "https://accounts.spotify.com/en/authorize",
accessTokenUrl: "https://accounts.spotify.com/api/token",
responseType: "code"
)
lazy var internalWebViewController: WKWebViewController = {
let controller = WKWebViewController()
controller.view = UIView(frame: UIScreen.main.bounds)
controller.loadView()
controller.viewDidLoad()
return controller
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .purple
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
initAuthFlow()
}
fileprivate func initAuthFlow() -> Void {
oauthSwift.authorizeURLHandler = internalWebViewController
guard let callbackURL = URL(string: "oauthkeychainapp://oauthkeychain-callback") else { return }
oauthSwift.authorize(
withCallbackURL: callbackURL,
scope: "user-library-modify",
state: generateState(withLength: 20),
success: { (credential, response, params) in
print(credential)
}) { (error) in
print(error.localizedDescription)
}
}
}
extension HomeController: OAuthWebViewControllerDelegate {
func oauthWebViewControllerDidPresent() { }
func oauthWebViewControllerDidDismiss() { }
func oauthWebViewControllerWillAppear() { }
func oauthWebViewControllerDidAppear() { }
func oauthWebViewControllerWillDisappear() { }
func oauthWebViewControllerDidDisappear() { oauthSwift.cancel() }
}
WKWebViewController.swift
import UIKit
import WebKit
import OAuthSwift
class WKWebViewController: OAuthWebViewController {
var webView: WKWebView!
var targetURL: URL?
override func viewDidLoad() {
super.viewDidLoad()
}
override func handle(_ url: URL) {
targetURL = url
super.handle(url)
loadAddressURL()
}
func loadAddressURL() {
guard let url = targetURL else { return }
let req = URLRequest(url: url)
self.webView?.load(req)
}
}
extension WKWebViewController: WKUIDelegate, WKNavigationDelegate {
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.allowsBackForwardNavigationGestures = true
webView.uiDelegate = self
webView.navigationDelegate = self
view = webView
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("loaded")
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// Check for OAuth Callback
if let url = navigationAction.request.url, url.scheme == "oauthkeychainapp" {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
self.dismiss(animated: true, completion: nil)
decisionHandler(.cancel)
return
}
// Restrict URL's a user can access
if let host = navigationAction.request.url?.host {
if host.contains("spotify") {
decisionHandler(.allow)
return
} else {
// open link outside of our app
UIApplication.shared.open(navigationAction.request.url!)
decisionHandler(.cancel)
return
}
}
decisionHandler(.cancel)
}
}
答案 0 :(得分:1)
您没有做任何更改应用程序状态的操作。由于此initAuthFlow
被再次调用,因此我认为Spotify为您提供了一个有效的会话,因此控制器被关闭,循环重复。
在成功完成oauthSwift.authorize
调用后,应将令牌放入KeyChain或安全的地方,并确保仅在该状态无效时才调用initAuthFlow
。