在 Xcode/Swift UIWebView 中控制网站 [英] Controlling website within Xcode/ Swift UIWebView

查看:36
本文介绍了在 Xcode/Swift UIWebView 中控制网站的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have created a very simple app which directs the user to a web app... one of the pages within the app allows you to search store stock for various different stores (store number entered manually or the nearest store located automatically) and then asks the user to enter the appropriate barcode... within the app I have therefore added a barcode scanner (a separate view controller) which captures the barcode and then returns to the uiwebview... but how can I automatically enter that barcode into a certain div field and then execute a js function... I have tried evaluatejavascript but to very little avail... Almost given up, you're my last hope! :)

视图控制器如下...

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)

    }


}

推荐答案

检查这个问题和回复:

使用 UIWebView 调用 Javascript

  1. 创建一个 js 方法来接收您的条形码.
  2. 当页面已经加载时,您可以使用 stringByEvaluatingJavaScriptFromString 调用它.

  1. Create a js method to receive your barcode.
  2. When the page is already loaded, you can call it by using stringByEvaluatingJavaScriptFromString.

let codebar = "34244342342424234"webView.stringByEvaluatingJavaScriptFromString("methodName("\(codebar)");")

let codebar = "34244342342424234" webView.stringByEvaluatingJavaScriptFromString("methodName("\(codebar)");")

<小时>

更新

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

I used this method some time ago: evaluateJavaScript in WKWebView, this example loads a jQuery and then change the background:

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); " +
    "})();")
}

这篇关于在 Xcode/Swift UIWebView 中控制网站的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆