[英]WkWebView Message handler doesn't return the value of textbox first time, but it does the second time I press the button
所以,我有一个带有文本框的 HTML 表单。 我在 WKWebView 中加载表单,并在我的 Swift 应用程序中使用消息处理程序,以便能够转储文本框的内容并稍后在 Swift 变量中使用它。
问题是,当我按下触发获取文本框值的 javascript function 的注册按钮时,第一个结果是空白。 不是 null,只是一个空格。
如果我再次按下按钮,我会得到文本框的实际内容。 我尝试使用 evaluateJavascript function 通过 ID 获取元素,同样的事情,第一次我什么也没得到,第二次我得到预期值。
我的 ViewController 的代码:
private var webkitview: WKWebView!
var lsusername = "";
var lspassword = "";
@IBOutlet weak var baseview: UIView!
@IBOutlet weak var registerAccountButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.webkitview = WKWebView(frame: self.baseview.bounds, configuration: self.getWKWebViewConfiguration())
baseview.addSubview(self.appvalleyRegistration)
baseview.translatesAutoresizingMaskIntoConstraints = false;
let url = URL(string: "https://redacted.com/registrationform.php")!
webkitview.load(URLRequest(url: url))
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
.darkContent
}
private func getWKWebViewConfiguration() -> WKWebViewConfiguration {
let userController = WKUserContentController()
userController.add(self, name: "observer")
let configuration = WKWebViewConfiguration()
configuration.userContentController = userController
return configuration
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let data = message.body as? [String : String], let passw = data["passw"], let email = data["email"] {
lsusername = email;
lspassword = passw;
} else {
print("No data.");
}
}
@IBAction func registerUser(_ sender: Any) {
webkitview.evaluateJavaScript("submitForm()");
showUser(email: lsusername, name: lspassword);
}
private func showUser(email: String, name: String) {
let userDescription = "\(email) \(name)"
let alertController = UIAlertController(title: "User", message: userDescription, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default))
present(alertController, animated: true)
}
我第一次使用showUser()
触发的警报是空白的,如果我再次按下按钮,它会显示从 Webkit 中的页面抓取的正确用户名和密码。
我的表格:
<body>
<script type="text/javascript">
function submitForm() {
var message = {
passw: document.getElementById("passw").value,
email: document.getElementById("email").value
};
window.webkit.messageHandlers.observer.postMessage(message);
}
</script>
<div class="container">
<h1>Welcome to my site</h1>
<p>Let's set up your account</p>
<hr>
<label for="email"><b>Email</b></label>
<input type="text" placeholder="Enter Email" name="email" id="email" required>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="passw" id="passw" required>
<label for="psw-repeat"><b>Repeat Password</b></label>
<input type="password" placeholder="Repeat Password" name="psw-repeat" id="psw-repeat" required>
</div>
</body>
我不明白为什么它第二次起作用,但不是第一次。
我尝试添加sleep()
以等待 JS 完全完成评估,但仍然没有。
evaluateJavascript
是一个异步的 function。 尝试添加一个完成块并在其中调用showUser
(但请确保在主线程上触发 UI 更新)。 我认为这应该可以解决您的直接问题:
webkitview.evaluateJavaScript("submitForm()") { [weak self] (_, _) in
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.showUser(email: self.lsusername, name: self.lspassword)
}
}
在更高级别的说明中,从 WKUserContentController 的didReceive
WKUserContentController
中调用showUser
是否更有意义? 我没有用过这么多,所以我在这里可能是错的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.