JavaScriptCore是IOS7以后苹果为了解决JS和原生之间的交互问题
1.非WebView环境下
一般有两种方式解决JS -> OC
1.OC主动调用JS
-(void)OCCallJS{
self.context = [[JSContext alloc] init];
NSString *js = @"function add(a,b) {return a+b}";
[self.context evaluateScript:js];
JSValue *addJS = self.context[@"add"];
JSValue *sum = [addJS callWithArguments:@[@(10),@(17)]];
NSInteger intSum = [sum toInt32];
NSLog(@"intSum: %zi",intSum);
}
2.JS中调用OC方法
a.通过block方式调用
-(NSInteger)add:(NSInteger)a and:(NSInteger)b{
return a+b;
}
-(void)JSCallOC_block{
self.context = [[JSContext alloc] init];
__weak typeof(self) weakSelf = self;
self.context[@"add"] = ^NSInteger(NSInteger a, NSInteger b){
return [weakSelf add:a and:b];
};
JSValue *sum = [self.context evaluateScript:@"add(4,5)"];
NSInteger intSum = [sum toInt32];
NSLog(@"intSum: %zi",intSum);
}
b.js通过对象方式调用
#pragma mark - js通过对象方式调用
- (void)JSCallOC_JSExport
{
NSLog(@"JSCallOC_JSExport");
self.jsContext = [JSContext new];
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
[JSContext currentContext].exception = exception;
NSLog(@"exception:%@",exception);
};
self.addObj = [AddJSExportObj new];
//self.jsContext[@"OCAddObj"] = self.addObj;//把oc对象映射成js对象 下面这句和这里效果是等价
[self.jsContext setObject:self.addObj forKeyedSubscript:@"OCAddObj"];
[self.jsContext evaluateScript:@"OCAddObj.token = OCAddObj.test()"];
[self.jsContext evaluateScript:@"OCAddObj.addAnd(2,30)"];
[self.jsContext evaluateScript:@"OCAddObj.TestTowParameter('参数A','参数B')"];
NSLog(@"OCAddObj.token1:%@",self.addObj.token);
//[self.jsContext evaluateScript:@"OCAddObj.testPromise('参数',function(resp){OCAddObj.token = resp})"];
[self.jsContext evaluateScript:@"OCAddObj.testPromise1(function(resp){})"];
//testPromise
NSLog(@"OCAddObj.token2:%@",self.addObj.token);
}
自定义对象必须实现JSExport协议。
//
// AddJSExportObj.h
// JavaScriptCore的理解
//
// Created by wangsheng on 2018/6/20.
// Copyright © 2018年 wangsheng. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
@protocol AddJSExport <JSExport>
//JSExportAs 这样适用于多个参数的情况,对js方法重命名,如果不这样写JS那边 调用方式为addAnd(),
//JSExportAs(add, - (NSInteger)add:(NSInteger)a and:(NSInteger)b);
- (NSString *)test;
- (NSInteger)add:(NSInteger)a and:(NSInteger)b;
JSExportAs(TestTowParameter, -(void)TestTowParameter:(NSString *)message1 SecondParameter:(NSString *)message2);
JSExportAs(testPromise, - (void)testPromise:(NSString *)arg success:(void(^)(NSString *))success);
JSExportAs(testPromise1, - (void)testPromise1:(void(^)(NSString *))arg);
@property (nonatomic, copy) NSString *token;
@property (nonatomic, assign) NSInteger sum;
@end
@interface AddJSExportObj : NSObject <AddJSExport>
@property (nonatomic, assign) NSInteger sum;
@property (nonatomic,copy)NSString *token;
@end
#import "AddJSExportObj.h"
@implementation AddJSExportObj
- (NSString *)test{
NSLog(@"js call oc method");
return @"oc return value to js";
}
- (NSInteger)add:(NSInteger)a and:(NSInteger)b
{
NSLog(@"come add:%li,b:%li",a,b);
return a+b;
}
-(void)TestTowParameter:(NSString *)message1 SecondParameter:(NSString *)message2
{
NSLog(@"TestTowParameter:%@,SecondParameter:%@",message1,message2);
}
- (void)testPromise:(NSString *)arg success:(void(^)(NSString *))success
{
NSLog(@"testPromise come here:%@",arg);
success(@"return value from oc to js");
}
- (void)testPromise1:(void(^)(NSString *))block
{
NSLog(@"testPromise1:%@",block);
block(@"11111");
}
@end
2.WebView环境下
1.通过拦截loadUrl方式实现JS -> OC
2.动态
1.获取JSContext上下文
JSContext *context = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
2.其他的同上面差不多
3.