javascript - 在 Xcode/Swift UIWebView 中控制网站

标签 javascript uiwebview swift3 xcode8

我创建了一个非常简单的应用程序,它将用户引导至网络应用程序...应用程序中的一个页面允许您搜索各种不同商店的商店库存(手动输入的商店编号或自动找到的最近的商店)然后要求用户输入适当的条形码...因此,在应用程序中我添加了一个条形码扫描仪(一个单独的 View Controller ),它捕获条形码然后返回到 uiwebview...但是我如何自动输入该条形码进入某个div字段,然后执行js函数...我尝试过evaluatejavascript,但收效甚微...几乎放弃了,你是我最后的希望! :)

查看 Controller 如下...

import UIKit
import WebKit


class ViewController: UIViewController {

    var webView: WebView




    @IBOutlet weak var searchText: UITextField!


    required init(coder aDecoder: NSCoder) {
        self.webView = WebView()
        super.init(coder: aDecoder)!
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(webView)
        webView.setPosition(view)
    }

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

    // MARK: Actions

    @IBAction func UseBCode(_ sender: Any) {
        webView.FillIn()
    }

    @IBAction func siteHomeBtn(_ sender: UIButton) {
        webView.setUrl("https://intranet.testsite.com/index.html")
    }

    @IBAction func searchBtn(_ sender: UIButton) {
        print ("Navigating to: \(searchText.text)")
        webView.setUrl(searchText.text)
    }

    @IBAction func appHomeBtn(_ sender: UIButton) {
        webView.setUrl("https://intranet.testsite.com/index.html")
    }

    @IBAction func backBtn(_ sender: UIButton) {
        webView.back()
    }


    @IBAction func forwardBtn(_ sender: UIButton) {
        //webView.forward()
    }

    @IBAction func unwindToHomeScreen(segue: UIStoryboardSegue) {
        dismiss(animated: true, completion: nil)
    //webView.FillIn()
        //webView.popup()

    }

    override func viewDidAppear(_ animated: Bool) {
        webView.FillIn()

    }

}


QRScannerController

import UIKit
import AVFoundation

var BCode = ""

class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

    @IBOutlet var Back2: UIButton!

    @IBOutlet var topBar: UIView!

    @IBOutlet var messageLabel: UILabel!



    var captureSession:AVCaptureSession?
    var videoPreviewLayer:AVCaptureVideoPreviewLayer?
    var qrCodeFrameView:UIView?

    let supportedCodeTypes = [AVMetadataObjectTypeUPCECode,
                              AVMetadataObjectTypeCode39Code,
                              AVMetadataObjectTypeCode39Mod43Code,
                              AVMetadataObjectTypeCode93Code,
                              AVMetadataObjectTypeCode128Code,
                              AVMetadataObjectTypeEAN8Code,
                              AVMetadataObjectTypeEAN13Code,
                              AVMetadataObjectTypeAztecCode,
                              AVMetadataObjectTypePDF417Code,
                              AVMetadataObjectTypeQRCode]

    override func viewDidLoad() {
        super.viewDidLoad()

        // Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter.
        let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

        do {
            // Get an instance of the AVCaptureDeviceInput class using the previous device object.
            let input = try AVCaptureDeviceInput(device: captureDevice)

            // Initialize the captureSession object.
            captureSession = AVCaptureSession()

            // Set the input device on the capture session.
            captureSession?.addInput(input)

            // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
            let captureMetadataOutput = AVCaptureMetadataOutput()
            captureSession?.addOutput(captureMetadataOutput)

            // Set delegate and use the default dispatch queue to execute the call back
            captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            captureMetadataOutput.metadataObjectTypes = supportedCodeTypes

            // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
            videoPreviewLayer?.frame = view.layer.bounds
            view.layer.addSublayer(videoPreviewLayer!)

            // Start video capture.
            captureSession?.startRunning()

            // Move the message label and top bar to the front
            //view.bringSubview(toFront: messageLabel)
            view.bringSubview(toFront: topBar)

            // Initialize QR Code Frame to highlight the QR code
            qrCodeFrameView = UIView()

            if let qrCodeFrameView = qrCodeFrameView {
                qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
                qrCodeFrameView.layer.borderWidth = 2
                view.addSubview(qrCodeFrameView)
                view.bringSubview(toFront: qrCodeFrameView)
            }

        } catch {
            // If any error occurs, simply print it out and don't continue any more.
            print(error)
            return
        }
    }

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


    // MARK: - AVCaptureMetadataOutputObjectsDelegate Methods

    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {

        // Check if the metadataObjects array is not nil and it contains at least one object.
        if metadataObjects == nil || metadataObjects.count == 0 {
            qrCodeFrameView?.frame = CGRect.zero
            //messageLabel.text = "No barcode detected"
            return
        }

        // Get the metadata object.
        let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject

        if supportedCodeTypes.contains(metadataObj.type) {
            // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
            let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
            qrCodeFrameView?.frame = barCodeObject!.bounds

            if metadataObj.stringValue != nil {
                messageLabel.text = "Use " + metadataObj.stringValue

                // Copy the barcode text to the clipboard.
                let clipboard = UIPasteboard.general
                clipboard.string = metadataObj.stringValue
            view.bringSubview(toFront: messageLabel)

                BCode = metadataObj.stringValue


                }

            }
        }
    }

Webview.script... the fillin function is me playing (to very little avail! :(

import UIKit
import WebKit

class WebView : WKWebView {

    /**
     Initialize the WKWebView.
     */
    init(){
        let webConfig:WKWebViewConfiguration = WKWebViewConfiguration()
        super.init(frame:CGRect.zero,configuration:webConfig)
        self.translatesAutoresizingMaskIntoConstraints = false
        self.allowsBackForwardNavigationGestures = true

        createHomePage()
    }


    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    /**
     Set the position for the WKWebView.
     */
    func setPosition(_ view: UIView) {
        self.translatesAutoresizingMaskIntoConstraints = false;
        let height = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: -60)
        let width = NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 1, constant: 0)
        let top = NSLayoutConstraint(item:self,attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 20)
        view.addConstraints([height, width, top])
    }

    /**
     Set the url the webview should display.
     */
    func setUrl(_ url:String!) {
        if url != nil {
            let url = URL(string:url)
            let request = URLRequest(url:url!)
            self.load(request)
        }
    }

    /**
     Create the home page.
     */
    func createHomePage() {
        self.setUrl("https://intranet.testsite.com/index.html")
        drawHomePage()
    }

    /**
     Draw the home page.
     */
    func drawHomePage() {
        let javaSCriptString="document.body.style.background=\"#ffc\""
        //self.loadHTMLString("<h1>Top20</h1>", baseURL: nil)
        self.evaluateJavaScript(javaSCriptString, completionHandler: nil)
    }

    /**
     Go to the home page.
     */
    func setAppHome() {
        print("The first item is \(self.findFirstItem()?.url)")
        let item = findFirstItem()
        if item != nil {
            self.go(to: item!)
            drawHomePage()
        }
    }

    /**
     Find the first item in the list of websites.
     */
    func findFirstItem() -> WKBackForwardListItem? {
        var index=0
        if (self.backForwardList.item(at: 0)==nil) {
            return nil
        }
        while self.backForwardList.item(at: index) != nil {
            index -= 1
        }
        return self.backForwardList.item(at: index+1)
    }

    /**
     Handle forward navigation.
     */
    func forward() {
        if self.canGoForward {
            self.goForward()
        } else {
            print("Cannot go forward.")
        }
    }

    /**
     Handle backward navigation.
     */
    func back(){
        if self.canGoBack {
            self.goBack()
            //self.evaluateJavaScript("document.getElementByID('barcode').innerHTML = '" + BCode + "'", completionHandler: nil)
        } else {
            print("Cannot go backwards.")
        }
    }

    func FillIn() {

        // fill data
        //let savedUsername = "USERNAME"
        //let savedPassword = "PASSWORD"
        let javaSCriptString="document.getElementByID('barcode').innerHTML = '" + BCode + "'"
        //self.loadHTMLString("<h1>Top20</h1>", baseURL: nil)
        self.evaluateJavaScript(javaSCriptString, completionHandler: nil)

        self.evaluateJavaScript("document.getElementByID('barcode').innerHTML = '" + BCode + "'")

        let source="appfunction('" + BCode + "'"
        //self.loadHTMLString("<h1>Top20</h1>", baseURL: nil)
        self.evaluateJavaScript(source)

        self.evaluateJavaScript("document.getElementByID('barcode').innerHTML = '" + BCode + "'")
        //let javaSCriptString="functiontofindIndexByKeyValue(eval('BarCode'), 'label', '\(BCode)', 'value')"


        let PArt = self.evaluateJavaScript(javaSCriptString)

        let DC01Stock = self.evaluateJavaScript("functiontofindIndexByKeyValue(eval('DCStock'), 'PArt', PArt.value, 'DC01')")

    }
    func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = false

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

    }


}

最佳答案

检查此问题和回复:

Calling Javascript using UIWebView

  1. 创建一个 js 方法来接收条形码。
  2. 页面加载完毕后,您可以使用 stringByEvaluatingJavaScriptFromString 调用它。

    让代码栏=“34244342342424234” webView.stringByEvaluatingJavaScriptFromString("methodName("\(codebar)");")

<小时/>

更新

我前段时间用过这个方法:WKWebView中的evaluateJavaScript,这个例子加载一个jQuery,然后改变背景:

var navigator : WKWebView!

func runJS(js:String) {
    navigator.evaluateJavaScript(js) {
        res, error in
        print(res ?? "no res", error ?? "no error")
    }
}

@IBAction func changeBackground(_ sender: Any) {
    navigator.evaluateJavaScript("jQuery('body').css('background', 'magenta!important')") {res, error in print(error ?? "no error buton 1")}
}


@IBAction func loadJQuery(_ sender: Any) {
    //Load jQuery library using plain JavaScript
    runJS(js: "(function(){ " +
        "var newscript = document.createElement('script'); " +
        "newscript.type = 'text/javascript'; " +
        "newscript.async = true; " +
        "newscript.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js'; " +
        "(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(newscript); " +
    "})();")
}

关于javascript - 在 Xcode/Swift UIWebView 中控制网站,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42236998/

相关文章:

javascript - 如何使 Angular 仅影响同一行的模型和范围

xcode - 如何在 Swift 中以编程方式添加约束

iphone - UIWebView,启用触摸保存图像,就像在移动 Safari 中一样

ios - subview 大小错误

ios - 如何删除Digit的登录 session ?

javascript - 比较 es6 类外部变量之间的内存使用情况并绑定(bind)到此

javascript - 方法调用模式不起作用?

javascript - 使用 react-sidebar 更改侧边栏项目上的主要内容单击

iOS在webview中加载Base 64编码数据

ios - Spotify SDK 缺少 token 刷新服务?