? ? ? ? 在UIWebview里面一般有兩種方法與JS交互库正,一種是JSContext,另外一種就是攔截協(xié)議褥符。而使用JSContext與JS交互的同學(xué),一般都對webViewDidFinishLoad這個代理比較熟悉趟大,因為一般來說和網(wǎng)上的的多數(shù)資料都會讓你在這個代理里面注入JSContext對象魂迄。但是這時候就會導(dǎo)致一個問題惋耙,需要全部加載JS的東西后才能與JS進(jìn)行交互绽榛,有時候前端會提出需要在加載的中途進(jìn)行交互灭美。
? ? ? ? 其實UIWebview里面還有一個webViewDidStartLoad代理方法届腐,如果你在這個方法里面也注入JSContext對象硬萍,在某種程度上可以解決這個問題围详,但是在打開webview里面的二級界面的時候可能會出現(xiàn)問題,因為可能在與JS交互的時候,JSContext提前銷毀了畜普,因為他是在webViewDidStartLoad中注入的漠嵌。如果你在- (void)viewDidLoad中注入,應(yīng)該也會有同一個問題化撕。
? ? ? ? 這個時候可以使用webkit的didCreateJavaScriptContext這個API植阴,這樣可以比較完美的解決上面提出的問題憾朴≈诶祝或者也可以使用UIWebView-TS_JavaScriptContext這個開源庫,當(dāng)然這個開源庫其實也是使用了這個API鸡岗,didCreateJavaScriptContext的具體代碼如下
#import 《Foundation/Foundation.h》
#import 《JavaScriptCore/JavaScriptCore.h》
@interface NSObject_JSContextTracker : NSObject
@end
#import "NSObject+JSContextTracker.h"
@implementation NSObject (JSContextTracker)
- (void)webView:(id)unused didCreateJavaScriptContext:(JSContext *)ctx forFrame:(id)alsoUnused {
if (!ctx)
return;
[[NSNotificationCenter defaultCenter] postNotificationName:@"LLCreatJSContex" object:ctx];
}
@end
最后就是在你需要調(diào)用的webview界面viewDidLoad里面注冊通知就OK
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(creatJSContex:) name:@"LLCreatJSContex" object:nil];
-(void)creatJSContex:(NSNotification*)noti
{
//? ? NSLog(@"%@",noti);
//注意以下代碼如果不在主線程調(diào)用會發(fā)生閃退狠鸳。
dispatch_async( dispatch_get_main_queue(), ^{
self.jsContext = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.jsContext[@"czb"] = self;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"異常信息:%@", exceptionValue);
};
});
}