iOS开发关于JavaScriptCore的模型注入问题

注意点:

1.所有的与JS交互回到iOS的方法,都是在子线程的,所以刷新UI需回到主线程.

2.关于H5多页面,有网络请求的环境下,如果发现debug时模型没值或者不存在,解决方法如下:

iOS中:webViewDidFinishLoad:方法中,重新引入一次模型的jsContext环境

image

JS中:需要加一个延时:(下图是已经修改正常的情况)

iOS开发关于JavaScriptCore的模型注入问题_第1张图片
image

最后在Google上发现已经有一位大神做了这方面的处理了,总的来说,我个人认为在JavaScript环境中注入的model对象会在js异常时释放,所以造成了model对象为undefined或者null,下面贴上大神的代码:

UIWebView+TS_JavaScriptContext.h


#import

#import

@protocolTSWebViewDelegate

@optional

- (void)webView:(UIWebView *)webView didCreateJavaScriptContext:(JSContext*) ctx;

@end

@interfaceUIWebView (TS_JavaScriptContext)

@property(nonatomic,readonly) JSContext* ts_javaScriptContext;

@end

UIWebView+TS_JavaScriptContext.m


#import "UIWebView+TS_JavaScriptContext.h"

#import

#import

staticconstcharkTSJavaScriptContext[] ="ts_javaScriptContext";

staticNSHashTable* g_webViews =nil;

@interfaceUIWebView (TS_JavaScriptCore_private)

- (void) ts_didCreateJavaScriptContext:(JSContext *)ts_javaScriptContext;

@end

@protocolTSWebFrame

- (id) parentFrame;

@end

@implementationNSObject (TS_JavaScriptContext)

- (void) webView: (id) unused didCreateJavaScriptContext: (JSContext*) ctx forFrame: (id) frame

{

    NSParameterAssert( [frame respondsToSelector:@selector( parentFrame )] );

    // only interested in root-level frames

    if( [frame respondsToSelector:@selector( parentFrame) ] && [frame parentFrame] !=nil)

        return;

    void(^notifyDidCreateJavaScriptContext)() = ^{

        for( UIWebView* webViewing_webViews )

        {

            NSString* cookie = [NSString stringWithFormat:@"ts_jscWebView_%lud", (unsignedlong)webView.hash ];

            [webView stringByEvaluatingJavaScriptFromString: [NSString stringWithFormat:@"var %@ = '%@'", cookie, cookie ] ];

            if( [ctx[cookie].toString isEqualToString: cookie] )

            {

                [webView ts_didCreateJavaScriptContext: ctx];

                return;

            }

        }

    };

    if( [NSThread isMainThread] )

    {

        notifyDidCreateJavaScriptContext();

    }

    else

    {

        dispatch_async( dispatch_get_main_queue(), notifyDidCreateJavaScriptContext );

    }

}

@end

@implementationUIWebView (TS_JavaScriptContext)

+ (id) allocWithZone:(struct_NSZone *)zone

{

    staticdispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        g_webViews = [NSHashTable weakObjectsHashTable];

    });

    NSAssert( [NSThread isMainThread],@"uh oh - why aren't we on the main thread?");

    idwebView = [superallocWithZone: zone];

    [g_webViews addObject: webView];

    returnwebView;

}

- (void) ts_didCreateJavaScriptContext:(JSContext *)ts_javaScriptContext

{

    [selfwillChangeValueForKey:@"ts_javaScriptContext"];

    objc_setAssociatedObject(self, kTSJavaScriptContext, ts_javaScriptContext, OBJC_ASSOCIATION_RETAIN);

    [selfdidChangeValueForKey:@"ts_javaScriptContext"];

    if( [self.delegate respondsToSelector:@selector(webView:didCreateJavaScriptContext:)] )

    {

        id delegate = (id)self.delegate;

        [delegate webView:selfdidCreateJavaScriptContext: ts_javaScriptContext];

    }

}

- (JSContext*) ts_javaScriptContext

{

    JSContext* javaScriptContext = objc_getAssociatedObject(self, kTSJavaScriptContext );

    returnjavaScriptContext;

}

@end

最后demo地址

你可能感兴趣的:(iOS开发关于JavaScriptCore的模型注入问题)