DO
WKUserContentController* ucc = self.webView.configuration.userContentController;
[ucc addScriptMessageHandler:self name:@"serverTimeCallbackHandler"]; // add
[ucc removeScriptMessageHandlerForName:@"serverTimeCallbackHandler"]; // remove
[ucc addScriptMessageHandler:self name:@"serverTimeCallbackHandler"]; // add
...并且不会从JavaScript调用window.webkit.messageHandlers.serverTimeCallbackHandler.postMessage(<messageBody>)
。
我在使用WebKit.framework
时遇到了问题。这要么是框架的错误,要么是对它的不当使用。
我有一个与网页互动的.js
文件。在交互结束时,脚本会调用window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
(function() {
var timeZoneCoockieName = 'cTz';
function getServerTimeWithTimeZone() {
PageMethods.GetServerTime(function(time) {
var serverTime = time;
var timezone = getCookie(timeZoneCoockieName);
var message = {'time': serverTime, 'timezone': timezone};
window.webkit.messageHandlers.serverTimeCallbackHandler.postMessage(message);
});
}
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
getServerTimeWithTimeZone();
})();
基本上,脚本调用页面方法,从服务器检索时间并在回调时查找存储在cookie中的时区。
本机组件旨在包装此调用并公开方便的API以检索日期/时区信息。
- (void)getServerTimeWithCompletion:((^)(id, NSError *))completion {
// Adding same message handler twice, leads to an exception.
// Removing message handler with the same name, just in case.
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"serverTimeCallbackHandler"];
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"serverTimeCallbackHandler"];
self.getServerTimeCompleteBlock = completion;
NSString * jsPath = [[NSBundle mainBundle] pathForResource:@"GetServerTime" ofType:@"js"];
if (![jsPath isBlank]) {
NSError* encodingError = nil;
NSString* jsContent = [NSString stringWithContentsOfFile:jsPath
encoding:NSUTF8StringEncoding
error:&encodingError];
if (!encodingError) {
[self.webView evaluateJavaScript:jsContent completionHandler: ^(id _Nullable result, NSError * _Nullable evalError) {
if (evalError) {
if (completion) { completion(nil, evalError); }
}
}];
} else {
if (completion) { completion(nil, encodingError); }
}
}
else {
if (completion) { completion(nil, nil); }
}
}
现在,如果用户调用此方法两次,则第二次不从JavaScript调用处理程序。
Web调试器附加到应用程序的Web视图,记录错误:
InvalidAccessError: DOM Exception 15: A parameter or an operation was not supported by the underlying object.