此处的目标是在webView
的网址发生变化时进行检测。由于WKWebView类的didCommit
和didStartProvisionalNavigation
函数在使用WebView中的某些元素时似乎总是闪现,我现在必须添加一个观察者来获取WebView&# 39;网址值的变化。
到目前为止,我已创建了名为checkURL
的自己的通知扩展程序:
迅速进展
extension Notification.Name {
static let checkURL = Notification.Name("checkURL")
}
NotificationCenter.default.post(name: .checkURL, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(getter: webView.url), name: .checkURL, object: webView.url)
Objective-C解决方案(KVO)
// Add an observer
[webView_ addObserver:self forKeyPath:@"URL" options:NSKeyValueObservingOptionNew context:NULL];
// Method that gets called when the URL value changes
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
// Code
}
如果URL值发生变化,我将如何应用Objective-C代码来触发函数?我仍然试图围绕通知以及它们如何处理对象值,所以任何解释都会非常有用!
感谢您阅读!
编辑:为了清理问题,我将重新提出问题:
由于didCommit
和didStartProvisionalNavigation
似乎总是无法解决(特别是在使用基于JavaScript的网站以及PHP时),您会不断看到网址被更改使用#
和诸如此类的符号;但是,如前所述,内置的WKWebView功能似乎无法捕获这些功能。所以我在这里尝试做的是找到一种解决方法来捕获对URL所做的任何类型的更改,无论它是否只是#
等等。最好保持代码完全是Swift - 如我仍在学习。 :)
答案 0 :(得分:2)
首先,请原谅这个答案中的(很多)假设,但我无法评论要求澄清。
其次,我建议给NSNotificationCenter reference一个好读。另外,如果我没记错的话,this writeup关于通知的内容对我来说非常有帮助。
现在到实际代码。如果我理解你的困境(除了必须一起使用Objective-C和Swift,这总是很有趣),你试图在URL更改时发出通知,以便你的Swift代码可以对新URL做一些事情
由于您的快速代码正在倾听通知,您不希望将其发布到那里。相反,通知应该发布在KVO回调中,如下所示:
// I have also changed the 'URL' to 'url' as I suspect that KVO is case-sensitive
// and replaced NULL with nil as it is generally a better practice to use it.
[webView_ addObserver:self forKeyPath:@"url" options:NSKeyValueObservingOptionNew context:nil];
// Method that gets called when the URL value changes
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if (sender == webView_ && [keyPath isEqualToString:@"url"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"checkURL" object:self];
}
}
这会将通知发送给任何观察者,例如Swift类。 Swift代码必须改为:
extension Notification.Name {
static let checkURL = Notification.Name("checkURL")
}
// Notice that the call to post(name:object:) has been removed.
// The 'object' parameter is only used for filtering out the sender of the notification.
NotificationCenter.default.addObserver(self, selector: #selector(doSomething(notification:)), name: .checkURL, object: nil)
// We can get the notification in the first parameter.
func doSomething(notification: Notification) {
// Do something, like reading the URL from the web view.
}
现在,如果您在Swift代码中不引用了webview,则可以在发布通知时传递userInfo参数中的值,如下所示:
[[NSNotificationCenter defaultCenter] postNotificationName:@"checkURL" object:self userInfo:@{ @"url" : webView.url }];
然后您可以在通知回调中读取userInfo:
func doSomething(notification: Notification) {
let url = notification.userInfo["url"]
// Do something with the url.
}