首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift:使用evaluateJavascript

Swift:使用evaluateJavascript
EN

Stack Overflow用户
提问于 2015-02-11 09:18:14
回答 2查看 7.7K关注 0票数 2

我是Swift开发的新手,我有一个我正在开发的混合应用程序,我已经连接了身份验证。当用户使用设备上的指纹传感器进行身份验证时,我希望触发JS或以其他方式与WKWebView交互……但由于某些原因,我似乎不能让它工作。我可以做一些简单的事情,比如改变窗口HREF。但是如果我做一些更复杂的事情,它要么什么都不做,要么失败。

下面是我的viewController的代码:

代码语言:javascript
复制
    import UIKit
    import WebKit
    import LocalAuthentication

    class ViewController: UIViewController, WKScriptMessageHandler, WKUIDelegate, WKNavigationDelegate {

        @IBOutlet var containerView : UIView! = nil

        // @IBOutlet weak var webView: UIWebView!
        var webView: WKWebView?
        var contentController = WKUserContentController();

        @IBOutlet var activityIndicatorView: UIActivityIndicatorView!

        override func viewDidLoad() {
            super.viewDidLoad()

            // append the userAgent and ensure it contains our browser detect regEx
            let userAgent = UIWebView().stringByEvaluatingJavaScriptFromString("navigator.userAgent")! + " iPad"
            NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent" : userAgent])

            // add JS content controller

            var config = WKWebViewConfiguration()
            config.userContentController = contentController

            // instantiate the web view
            let webView = WKWebView(frame: CGRectZero, configuration: config)
            webView.setTranslatesAutoresizingMaskIntoConstraints(false)
            webView.navigationDelegate = self
            view.addSubview(webView)

            // customize sizing
            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: NSLayoutFormatOptions.allZeros, metrics: nil, views: ["webView": webView]))

            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: NSLayoutFormatOptions.allZeros, metrics: nil, views: ["webView": webView]))

            // open the URL for the app
            let urlPath = "http://im_a_url"
            let url: NSURL = NSURL(string: urlPath)!
            let request = NSURLRequest(URL: url)
            webView.loadRequest(request)

        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }

        func webView(webView: WKWebView!, didStartProvisionalNavigation navigation: WKNavigation!) {
          UIApplication.sharedApplication().networkActivityIndicatorVisible = true
        }

        func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
   UIApplication.sharedApplication().networkActivityIndicatorVisible = false

            // trigger authentication
            authenticateUser()

        }

        func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {

        }

        func logInWithStoredCredentials() {
            println("successful auth - log in");
            // TO DO - use core data to stor user credentials
            webView!.evaluateJavaScript("document.getElementById('anonymousFormSubmit').click();", nil)

        }

        func authenticateUser() {
            // Get the local authentication context.
            let context = LAContext()

            // Declare a NSError variable.
            var error: NSError?

            // Set the reason string that will appear on the authentication alert.
            var reasonString = "Authentication is needed to access aware360Suite."

            // Check if the device can evaluate the policy.
            if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error) {
                [context .evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success: Bool, evalPolicyError: NSError?) -> Void in

                    if success {
                        self.logInWithStoredCredentials()
                        // self.webView?.evaluateJavaScript("document.getElementById('auiAuthSubmitBtn').click();", nil)
                    }
                    else{
                        // If authentication failed then show a message to the console with a short description.
                        // In case that the error is a user fallback, then show the password alert view.
                        println(evalPolicyError?.localizedDescription)

                        switch evalPolicyError!.code {

                        case LAError.SystemCancel.rawValue:
                            println("Authentication was cancelled by the system")

                        case LAError.UserCancel.rawValue:
                            println("Authentication was cancelled by the user")

                        case LAError.UserFallback.rawValue:
                            println("User selected to enter custom password")
                            // self.showPasswordAlert()

                        default:
                            println("Authentication failed")
                            // self.showPasswordAlert()
                        }
                    }

                })]
            }
            else{
                // If the security policy cannot be evaluated then show a short message depending on the error.
                switch error!.code{

                case LAError.TouchIDNotEnrolled.rawValue:
                    println("TouchID is not enrolled")

                case LAError.PasscodeNotSet.rawValue:
                    println("A passcode has not been set")

                default:
                    // The LAError.TouchIDNotAvailable case.
                    println("TouchID not available")
                }


            }

        }

    }

问题出在成功的身份验证方法中:

代码语言:javascript
复制
func logInWithStoredCredentials() {
        println("successful auth - log in");
        // TO DO - use core data to use stored user credentials
        webView!.evaluateJavaScript("document.getElementById('anonymousFormSubmit').click();", nil)

    }

我似乎在这里找不到webView的句柄。如果我尝试在这里实际计算脚本,它会抛出以下错误:

代码语言:javascript
复制
2015-02-10 17:07:32.912 A360[2282:462860] -[UIWebView evaluateJavaScript:completionHandler:]: unrecognized selector sent to instance 0x1741897f0
2015-02-10 17:07:32.916 A360[2282:462860] <NSXPCConnection: 0x178103960> connection to service named com.apple.CoreAuthentication.daemon: Warning: Exception caught during decoding of received reply to message 'evaluatePolicy:options:reply:', dropping incoming message and calling failure block.

Exception: -[UIWebView evaluateJavaScript:completionHandler:]: unrecognized selector sent to instance 0x1741897f0

我完全不知所措。我知道我在这里没有正确的WebView句柄,因为我知道如果我在从视图成功导航之后立即尝试这样的操作,它将工作得很好,例如:

代码语言:javascript
复制
func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false

        webView.evaluateJavaScript("document.getElementById('anonymousFormSubmit').click();", nil)

    }

很明显,在我的logInWithStoredCredentials函数中,它丢失了webView的上下文。

如何在我的logInWithStoredCredentials函数中获得正确的webView句柄?

很抱歉-我知道这是一个相当基本的问题,但我已经用头撞了几个小时了,这是一个非常紧迫的问题,我必须尽快解决。

EN

回答 2

Stack Overflow用户

发布于 2015-02-24 06:08:45

看起来你在UI中使用了UIWebView而不是WKWebView:

代码语言:javascript
复制
Exception: -[UIWebView evaluateJavaScript:completionHandler:]: unrecognized selector sent to instance 0x1741897f0

您应该实例化一个WKWebView实例。还要注意,WKWebView不能在Interface Builder中创建,您必须在运行时将其添加到视图层次结构中。

票数 2
EN

Stack Overflow用户

发布于 2015-10-19 22:22:51

你有var webView: WKWebView吗?然后在viewDidLoad中将其重新定义为let webView = WKWebView(frame: CGRectZero, configuration: config),删除webView前面的字母,它就可以工作了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28444969

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档