如何在UIWebview未加载完成之前获取JSContext对象

        在UIWebview里面一般有两种方法与JS交互,一种是JSContext,另外一种就是拦截协议。而使用JSContext与JS交互的同学,一般都对webViewDidFinishLoad这个代理比较熟悉,因为一般来说和网上的的多数资料都会让你在这个代理里面注入JSContext对象。但是这时候就会导致一个问题,需要全部加载JS的东西后才能与JS进行交互,有时候前端会提出需要在加载的中途进行交互。

        其实UIWebview里面还有一个webViewDidStartLoad代理方法,如果你在这个方法里面也注入JSContext对象,在某种程度上可以解决这个问题,但是在打开webview里面的二级界面的时候可能会出现问题,因为可能在与JS交互的时候,JSContext提前销毁了,因为他是在webViewDidStartLoad中注入的。如果你在- (void)viewDidLoad中注入,应该也会有同一个问题。

        这个时候可以使用webkit的didCreateJavaScriptContext这个API,这样可以比较完美的解决上面提出的问题。或者也可以使用UIWebView-TS_JavaScriptContext这个开源库,当然这个开源库其实也是使用了这个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

最后就是在你需要调用的webview界面viewDidLoad里面注册通知就OK

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(creatJSContex:) name:@"LLCreatJSContex" object:nil];

-(void)creatJSContex:(NSNotification*)noti

{

//    NSLog(@"%@",noti);

//注意以下代码如果不在主线程调用会发生闪退。

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);

};

});

}

你可能感兴趣的:(如何在UIWebview未加载完成之前获取JSContext对象)