I was wondering if it would be possible to autofill elements in the WKWebView? Or like auto click on them or something like that.
I want to make a script that autofill's info in a webbrowser.
(Maybe with javascript or something.)
I was wondering if it would be possible to autofill elements in the WKWebView? Or like auto click on them or something like that.
I want to make a script that autofill's info in a webbrowser.
(Maybe with javascript or something.)
iOS 11.0 had introduced username and password autofill in apps and it is possible to use it also in WKWebView.
Please refer to Enabling Password AutoFill on an HTML Input Element from Apple's docs.
In short:
<input id="password-text-field" type="password" autocomplete="current-password"/>
<input id="user-text-field" type="email" autocomplete="username"/>
I did custom implement that auto-fill feature, would like to share
use it with
let data = AutoFillData(fName: "Jhon")
webView.evaluateJavaScript(data.createJSString(), completionHandler: nil)
It searches dom elements with name and id
struct AutoFillData {
var fName: String?
var lName: String?
var email: String?
var phone: String?
var shipAddress: String?
var shipCity: String?
var shipState: String?
var shipCountry: String?
var zip: String?
enum KeyNames: String, CaseIterable {
case first_name, customerFirstName,
last_name, customerLastName,
name,
email, customerEmail,
phone, alternatePhone, phoneNumber, phoneNumber2 = "phone-number",
shipAddress = "ship-address", addressLine1, addressLine2,
shipCity = "ship-city", city,
shipState = "ship-state", state,
shipZip = "ship-zip", zip, pincode,
shipCountry = "ship-country", country
}
func getData(keyName: KeyNames) -> String? {
switch keyName {
case .first_name, .customerFirstName: return fName
case .last_name, .customerLastName: return lName
case .name: return [fName, lName].compactMap { $0 }.joined(separator: " ")
case .email, .customerEmail: return email
case .phone, .alternatePhone, .phoneNumber, .phoneNumber2: return phone
case .shipAddress, .addressLine1, .addressLine2: return shipAddress
case .shipCity, .city: return shipCity
case .shipState, .state: return shipState
case .shipCountry, .country: return shipCountry
case .zip, .shipZip, .pincode: return zip
}
}
func createJSString() -> String {
var str = ""
KeyNames.allCases.forEach {
let value = getData(keyName: $0)?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
if !value.isEmpty {
str.append("""
var e = document.getElementsByName('\($0.rawValue)')[0];
if (e == null) {
e = document.getElementById('\($0.rawValue)');
}
if (e != null) {
e.value = '\(value)';
}
""")
}
}
return str
}
}