2015-02-11 210 views
1

我对Swift开发相当陌生,而且我正在开发一个混合应用程序,我已经连接了身份验证。当用户使用设备上的指纹传感器进行身份验证时,我想要触发JS或以其他方式与WKWebView进行交互......但出于某种原因,我似乎无法使其工作。我可以做简单的事情,比如改变窗口HREF ...但是如果我做更复杂的事情,它可能什么都不做,或者失败。Swift:使用evaluateJavascript

这里是我的viewController的代码:

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") 
       } 


      } 

     } 

    } 

的问题是,在成功的验证方法:

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

    } 

我似乎无法在这里得到一个处理web视图。如果我试图在这里实际评估脚本,它会抛出以下错误:

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在这里,因为我知道,如果我有过在视图中成功导航后立即尝试这样的操作时,它会正常工作,如:

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

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

    } 

很显然,在我的logInWithStoredCredentials函数中,它已经失去了webView的上下文。

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

对不起所有 - 我知道这是一个相当基本的问题,但我一直对我的头撞几个小时,这是一个非常紧迫的问题,我必须迅速解决。

+0

浏览一下新的[library](https://github.com/coshx/caravel),它可以帮助你;) – 2015-06-02 20:55:48

回答

2

它看起来像你的UIWebView而不是WKWebView在UI:

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

你应该实例化一个WKWebView实例,而不是。另外请注意,WKWebView无法在Interface Builder中创建,您必须在运行时将其添加到视图层次结构中。

0

您有var webView: WKWebView?在你的班级,但然后重新定义它在viewDidLoadlet webView = WKWebView(frame: CGRectZero, configuration: config) 删除让在webView前,让它工作。