注意点:
1.所有的与JS交互回到iOS的方法,都是在子线程的,所以刷新UI需回到主线程.
2.关于H5多页面,有网络请求的环境下,如果发现debug时模型没值或者不存在,解决方法如下:
iOS中:webViewDidFinishLoad:方法中,重新引入一次模型的jsContext环境
JS中:需要加一个延时:(下图是已经修改正常的情况)
最后在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