美文网首页UIWebViewiOS Developer
如何在UIWebview未加载完成之前获取JSContext对象

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

作者: 没有方向的石头 | 来源:发表于2017-11-28 10:54 被阅读197次

            在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对象

        本文链接:https://www.haomeiwen.com/subject/abrsbxtx.html