在 Xcode/Swift UIWebView 中控制网站 [英] Controlling website within 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)
}
}
推荐答案
检查这个问题和回复:
- 创建一个 js 方法来接收您的条形码.
当页面已经加载时,您可以使用 stringByEvaluatingJavaScriptFromString 调用它.
- Create a js method to receive your barcode.
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屋!