更新不推荐使用的webkit objc项,以启用在javascript中运行的本机代码



我正在使用基于遗留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')
})();

这应该很好

相关内容

  • 没有找到相关文章

最新更新