如何让 Swift 与 Webview 交互?

Fiz*_*zix 1 xcode webview ios swift

我正在使用 Xcode 构建一个基本的 iOS 应用程序,它主要包含一个带有我的 Web 应用程序的 Web 视图。

我想知道是否有一种不错的方法可以在登录时将用户用户名保存到设备存储中,以便下次打开应用程序时可以自动输入。由于该应用程序是一个网络视图,我不相信有一种方法可以让用户保持登录状态(就像其他主要应用程序一样,例如 Facebook),所以我认为自动填充用户名将对他们有利。

我发现这个问题和答案可能会解决我的问题,尽管它是在很好的 Objective C 中。

我目前的尝试绝对没有任何作用:

let savedUsername = "testusername"

let loadUsernameJS = "document.getElementById(\"mainLoginUsername\").value = " + savedUsername + ";"

self.Webview.stringByEvaluatingJavaScriptFromString(loadUsernameJS)
Run Code Online (Sandbox Code Playgroud)

Swift 有可能实现这一点吗?

Cas*_*sey 5

为了存储密码,您应该使用钥匙串,特别是网络凭据。如果做得正确,这将允许您的应用程序使用通过 Safari 输入的任何现有钥匙串条目,并且还允许 Safari 访问通过您的应用程序保存的密码。

设置和检索的代码如下:

private let domain = "www.youdomain.com"

func saveWebCredentials(username: String, password: String, completion: Bool -> Void) {
    SecAddSharedWebCredential(domain, username, password) { error in
        guard error == nil else { print("error saving credentials: \(error)"); return completion(false) }
        completion(true)
    }
}

func getExistingWebCredentials(completion: ((String, String)?, error: String?) -> Void) {
    SecRequestSharedWebCredential(domain, nil) { credentials, error in
        // make sure we got the credentials array back
        guard let credentials = credentials else { return completion(nil, error: String(CFErrorCopyDescription(error))) }

        // make sure there is at least one credential
        let count = CFArrayGetCount(credentials)
        guard count > 0 else { return completion(nil, error: "no credentials stored") }

        // extract the username and password from the credentials dict
        let credentialDict = unsafeBitCast(CFArrayGetValueAtIndex(credentials, 0), CFDictionaryRef.self)
        let username = CFDictionaryGetValue(credentialDict, unsafeBitCast(kSecAttrAccount, UnsafePointer.self))
        let password = CFDictionaryGetValue(credentialDict, unsafeBitCast(kSecSharedPassword, UnsafePointer.self))

        // return via completion block
        completion((String(unsafeBitCast(username, CFStringRef.self)), String(unsafeBitCast(password, CFStringRef.self))), error: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

其用法如下:

// save the credentials
saveWebCredentials("hello", password: "world", completion: { success in

    // retrieve the credentials
    getExistingWebCredentials { credentials, error in
        guard let credentials = credentials else { print("Error: \(error)"); return }
        print("got username: \(credentials.0) password: \(credentials.1)")
    }
})
Run Code Online (Sandbox Code Playgroud)

更新

建议切换到使用 WKWebView,以便您可以轻松提取响应标头。这是样板代码:

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let webView = WKWebView(frame: self.view.bounds)
        webView.navigationDelegate = self
        self.view.addSubview(webView)

        webView.loadRequest(NSURLRequest(URL: NSURL(string: "https://www.google.com")!))
    }

    func webView(webView: WKWebView, decidePolicyForNavigationResponse navigationResponse: WKNavigationResponse, decisionHandler: (WKNavigationResponsePolicy) -> Void) {
        // make sure the response is a NSHTTPURLResponse
        guard let response = navigationResponse.response as? NSHTTPURLResponse else { return decisionHandler(.Allow) }

        // get the response headers
        let headers = response.allHeaderFields
        print("got headers: \(headers)")

        // allow the request to continue
        decisionHandler(.Allow);
    }
}
Run Code Online (Sandbox Code Playgroud)