JavaScriptCore中类和协议:
- JSContext:
JavaScript
上下文环境。
JSContext *jsContext = [webView valueForKeyPath:"documentView.webView.mainFrame.javaScraptContext"]; - JSValue:
JS
和OC
之间的数据和方法桥梁。- 从JS上下文中获取JS方法:
JSValue *jsFunc = jsContext[@"jsFunc"]; - 从本地JS代码中获得JS对象
JSContext *jsContext = [[JSContext alloc] init];
JSValue *localJS;
NSString *path = [[NSBundle mainBundle] pathForResource:@"script" ofType:@"js"];
NSString *scriptStr = [NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
localJS = [jsContext evaluateScript:scriptStr]; - 调用JS方法后获得数据
JSValue *jsFunc = localJS[@"jsFunc"];
JSValue *jsValue = [jsFunc callWithAruments:@[args1,args2...]];
Bool ocValue = [jsValue toBool];
- 从JS上下文中获取JS方法:
- JSManagedValue: 管理数据和方法的类。
- JSVirtualMachine: 处理线程关系。
- JSExport: 这是协议, 如果需要将一个OC对象回传给JS, 需要OC对象遵守此协议。
-
给JS传值
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>@protocol userInfoProtocol <JSExport> @property (nonatomic ,copy) NSString *result; @property (nonatomic ,copy) NSString *fullName; @end @interface XDUserInfoLoginResult:NSObject<userInfoProtocol> @property (nonatomic ,copy) NSString *result; @property (nonatomic ,copy) NSString *fullName; @end ----------------------------------------- //注入JS方法 self.jsContext[@"getLoginInfo"] = ^() { XDUserInfoLoginResult *result = [[XDUserInfoLoginResult alloc] init]; return result; };
-
给JS传方法
html代码
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> </head> <body> <div style="margin-top: 100px"> <h1>JavaScriptCore:OC和JS交互小记</h1> <input type="button" value="CallOC" onclick="nativeObj.callOC()"> </div> <script> var ocCallback = function(){ alert('success'); } </script> </body> </html>
oc代码
#import "ViewController.h" #import <JavaScriptCore/JavaScriptCore.h> @protocol JSObjcDelegate <JSExport> //实现JS中需要调用的callOC方法 - (void)callOC; @end @interface ViewController () <UIWebViewDelegate, JSObjcDelegate> @property (nonatomic, strong) JSContext *jsContext; @property (weak, nonatomic) IBOutlet UIWebView *webView; @end @implementation ViewController #pragma mark - Life Circle - (void)viewDidLoad { [super viewDidLoad]; NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"]; [self.webView loadRequest:[[NSURLRequest alloc] initWithURL:url]]; } #pragma mark - UIWebViewDelegate - (void)webViewDidFinishLoad:(UIWebView *)webView { //拿到JS上下文 self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //注入JS代码,定义JS中需要调用的nativeObj self.jsContext[@"nativeObj"] = self; self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; NSLog(@"异常信息:%@", exceptionValue); }; } #pragma mark - JSObjcDelegate //实现callOC方法 - (void)callOC { NSLog(@"callOC"); // JS调用OC成功之后在回调JS的方法ocCallback JSValue *ocCallback = self.jsContext[@"ocCallback"]; [ocCallback callWithArguments:nil]; } @end
-
OC执行JS代码方法:
// UIWebView的方法
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
// JavaScriptCore中JSContext的方法
- (JSValue *)evaluateScript:(NSString *)script;
- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL
相关应用
// 获取当前页面的title
NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"];
// 获取当前页面的url
NSString *url = [webview stringByEvaluatingJavaScriptFromString:@"document.location.href"];
// 阻止alert
[webView stringByEvaluatingJavaScriptFromString:@"window.alert=null;"];
//出现304白屏问题
if ([webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"].length < 1 ) {
HXLog(@"Reconstructing request...");
[self loadWithOutCacheUrl:self.currentUrl];
return;
}