2015-02-11 4 views
1

Я довольно новичок в разработке Swift, и у меня есть гибридное приложение, которое я разрабатываю, к которому я подключил аутентификацию. Когда пользователь аутентифицируется датчиком отпечатков пальцев на устройстве, я хочу запустить JS или иным образом взаимодействовать с WKWebView ... но по какой-то причине я не могу заставить его работать. Я могу делать простые вещи, такие как изменение окна HREF ... но если я делаю что-то более сложное, это либо ничего не делает, либо терпит неудачу.Swift: using оценитьJavascript

Вот код моего 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) 

    } 

Я не могу показаться, чтобы получить дескриптор Webview здесь. Если я попытаюсь на самом деле оценить сценарий здесь, это вызывает следующую ошибку:

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.

Как я могу получить правильную ручку для webView в моей функции logInWithStoredCredentials?

Извините, все - я знаю, что это довольно простой вопрос, но я уже несколько часов стучаю головой против него, и это очень важная проблема, которую я должен решить быстро.

+0

Взгляните на эту новую [библиотеку] (https://github.com/coshx/caravel), это может вам помочь;) –

ответ

2

Похоже, у вас есть UIWebView вместо WKWebView в вашем пользовательском интерфейсе:

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

Вы должны создать экземпляр экземпляр WKWebView вместо этого. Также обратите внимание, что WKWebView не может быть создан в Interface Builder, вам придется добавить его в иерархию представлений во время выполнения.

0

У вас есть var webView: WKWebView? в вашем классе, но затем переопределите его в viewDidLoad как let webView = WKWebView(frame: CGRectZero, configuration: config) Снимите флажок перед веб-браузером, и он должен работать.