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! :)
View controller as follows...
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)
}
}