我正在使用基于遗留webkit的应用程序在macOS原生应用程序(用objective-c编写的可可应用程序(上生成表单
以下回调在javascript加载到视图之前调用,并允许在即将加载的javascript中使用当前类代码(objc(。
- (void)webView:(WebView *)webView windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject {
[windowScriptObject setValue:self forKey:@"app"];
}
不幸的是,它早就被弃用了,我想使用更新后的webView对象WKWebView
的替代品。但是,上面的回调是来自WebFrameLoadDelegate
的委托方法,该方法也不推荐使用。也许有人知道如何使用WKWebView在javascript中注入我们的本地代码?
感谢
这就是使用WKWebView
的方法。YourWebView
是UIView或ViewController类。
@interface YourWebView () <WKNavigationDelegate, WKScriptMessageHandler>
- (void)injectWSKitScriptInUserContentController:(WKUserContentController*)userContentController;
@end
在-init或-initWithFrame:中的实现中
self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
self.autoresizesSubviews = YES;
self.wantsLayer = YES;
WKWebViewConfiguration* conf = [[WKWebViewConfiguration alloc] init];
conf.suppressesIncrementalRendering = NO;
conf.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
WKUserContentController* userContentController = [[WKUserContentController alloc] init];
[self injectWSKitScriptInUserContentController:userContentController];
[userContentController addScriptMessageHandler:self name:@"yourscript"];
conf.userContentController = userContentController;
#ifdef DEBUG
NSLog(@"Developer Extras Enabled");
[conf.preferences setValue:@YES forKey:@"developerExtrasEnabled"];
#endif
WKWebView *webView = [[WKWebView alloc] initWithFrame:frame configuration:conf];
webView.navigationDelegate = self;
将webView
添加到视图或需要它的地方,并定义一个注入js的方法。
-(void)injectWSKitScriptInUserContentController:(WKUserContentController*)userContentController {
NSBundle* bundle = [NSBundle bundleForClass:[YourWebView class]];
NSString* scriptLocation = [bundle pathForResource:@"yourscript" ofType:@"js"];
NSString* scriptSource = [NSString stringWithContentsOfFile:scriptLocation encoding:NSUTF8StringEncoding error:nil];
WKUserScript* userScript = [[WKUserScript alloc] initWithSource:scriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
[userContentController addUserScript:userScript];
}
然后按照协议在YourWebView中实现其他内容例如,与您的网络视图交互,如前进、重新加载、后退等。
最后,您将希望添加一个javascript文件作为应用程序的起点";yourscript.js">如上所述。
(function() {
"use strict";
var Events = {
listeners: { },
gc: function() {
var events = Object.keys(this.listeners)
for (var i = events.length - 1; i >= 0; i -= 1) {
var eventName = events[i],
listeners = this.listeners[eventName]
if (listeners.length === 0) {
delete this.listeners[eventName]
}
}
},
once: function(name, listener) {
if (name in this.listeners) {
this.listeners[name].push({ oneshot: true, listener: listener })
return
}
this.listeners[name] = [
{ oneshot: true, listener: listener },
]
},
on: function(name, listener) {
if (name in this.listeners) {
this.listeners[name].push({ listener: listener })
return
}
this.listeners[name] = [ { listener: listener } ]
},
off: function(name, listener) {
if ( ! (name in this.listeners)) {
return
}
var listeners = this.listeners[name]
for (var i = listeners.length - 1; i >= 0; i -= 1) {
if (listeners[i].listener === listener) {
listeners.splice(i, 1)
return
}
}
},
trigger: function(name, arg) {
if ( ! (name in this.listeners)) {
return
}
var event = { stopIteration: false, data: arg }
var listeners = this.listeners[name]
for (var i = 0; i < listeners.length; i += 1) {
var listener = listeners[i]
try {
listener.listener(event)
} catch (e) { }
if (listener.oneshot) {
listeners.splice(i, 1)
i -= 1
}
}
this.gc()
},
}
var ETimeout = new Error('WSKit: configuration timeout'),
_config = { resolve: null, reject: null, resolved: false }
window.WSKit = {
configuration: new Promise(function(resolve, reject) {
_config.resolve = resolve
_config.reject = reject
}),
addEventListener: function(name, listener, config) {
config = config || { }
if (config.oneshot) {
Events.once(name, listener)
} else {
Events.on(name, listener)
}
},
removeEventListener: function(name, listener) {
Events.off(name, listener)
},
dispatchEvent: function(name, arg) {
Events.trigger(name, arg)
},
}
setTimeout(function() {
if ( ! _config.resolved) {
_config.reject(ETimeout)
}
}, 5000)
WSKit.addEventListener('configure', function(ev) {
_config.resolve(ev.data)
})
window.webkit.messageHandlers.webscreen.postMessage('obtainconfiguration')
})();
这应该很好