学习iOS技术iOSiOS开发笔录

OC与JS数据交互

2016-05-18  本文已影响3618人  xshenpan
QQ20160518-0.png QQ20160518-1.png QQ20160518-2.png

#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>

//自己定义一个协议遵守JSExport协议,然后想要导出这些方法的类再遵守这个协议就可以了
@protocol ObjcExportMethod <JSExport>

//JSExportAs宏将 "- showNumber1:andNumber2:"方法名 转换为showNumber(param1, param2)
//如果不使用JSExportAs转换,那么在js中调用的函数名为showNumber1AndNumber2(param1, param2);
//注意:JSExportAs宏只适合转换有参的方法,不能转换无参的方法
JSExportAs(showNumber,
- (void)showNumber1:(NSNumber *)n1 andNumber2:(NSNumber *)n2
);

JSExportAs(returnSum,
- (NSNumber *)returnSumWithNum1:(NSNumber *)n1 andNum2:(NSNumber *)n2
);

JSExportAs(dictTest,
- (void)dictTest:(NSDictionary *)dict
);

JSExportAs(arrayTest,
- (void)arrayTest:(NSArray *)array
);

- (void)show;
- (NSString *)returnString;
- (NSDictionary *)returnDict;
- (NSArray *)returnArray;
@end

/**
  * UIViewController
  */
@interface ViewController () <UIWebViewDelegate, ObjcExportMethod>
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //加载本地测试网页
    [self.webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"]]];

}

#pragma mark - <ObjcExportMethod>

/**
 *  无参导出方法
 */
- (void)show
{
    NSLog(@"%s", __func__);
}
/**
 *  返回一个OC字符串到JavaScript
 */
- (NSString *)returnString
{
    return @"从OC返回成功";
}
/**
 *  返回一个OC数组到JavaScript
 */
- (NSArray *)returnArray
{
    return @[@(1), @"hello"];
}
/**
 *  返回一个OC字典到JavaScript
 */
- (NSDictionary *)returnDict
{
    return @{
             @"name" : @"jack",
             @"date" : @[@(1), @"hello"]
             };
}
/**
 *  从JavaScript接收两个NSNumber参数,计算他们的和并返回计算结果到JS
 */
- (NSNumber *)returnSumWithNum1:(NSNumber *)n1 andNum2:(NSNumber *)n2
{
    return @(n1.intValue + n2.intValue);
}
/**
 *  从JavaScript接收两个NSNumber类型的值,打印出来
 */
- (void)showNumber1:(NSNumber *)n1 andNumber2:(NSNumber *)n2
{
    NSLog(@"number1 = %@, number2 = %@", n1, n2);
}
/**
 *  从JavaScript接收一个字典
 */
- (void)dictTest:(NSDictionary *)dict
{
    NSLog(@"%@",dict);
}
/**
 *  从JavaScript接收一个数组
 */
- (void)arrayTest:(NSArray *)array
{
    NSLog(@"%@", array);
}


#pragma mark - <UIWebViewDelegate>

/**
 *  完成加载
 */
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    //得到当前页面的JSContext,如果不在这里获得当前网页的context可能有问题
    JSContext *js = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //设置 js 代码中的method对象为控制器
    js[@"method"] = self;
    
    //在OC中执行js并取得js返回的数据
    //方式1 使用JSContext的对象方法执行JS脚本
    NSString *jsScript = @"document.title";     //获取网页标题
    //evaluateScript方法返回的是JSValue类型的对象,需要将类型转换为OC对象
    NSString *title = [js evaluateScript:jsScript].toString;
    self.navigationItem.title = title;
    NSLog(@"evaluateScript --->  %@",title);

    //方式2 使用webView的对象方法执行js,该方法返回的数据类型始终是NSString,不管JS实际传递过来的是什么类型,
    //如JS传递过来的是10 那么该方法的返回值任然是字符串
    title = [webView stringByEvaluatingJavaScriptFromString:jsScript];
    NSLog(@"stringByEvaluating ---> %@", title);
}

@end

<html>
    <head>
    <meta charset="UTF-8"/>
    <title>测试网页</title>
    <script>
        //遍历数组
        function ArrayFun(array)
        {
            for(var i = 0; i < array.length; i++)
            {
                alert(array[i]);
            }
        }
        // 遍历字典
        function DictionaryFun(dict)
        {
            for (var key in dict)
            {
                alert(key + " : " + dict[key]);
            }
        }
    </script>
    </head>
    

    <body>
        <h5 style="color:blue" onclick="method.show();">调用OC无参无返回值方法</h5>
        <h5 style="color:blue" onclick="alert(method.returnString());">从OC返回字符串</h5>
        <h5 style="color:blue" onclick="method.showNumber(1,2);">传递2个整数到OC</h5>
        <h5 style="color:blue" onclick="alert(method.returnSum(10,20));">传递2个整数到OC,得到他们的和</h5>
        <h5 style="color:blue" onclick="method.arrayTest([1,2,'hello oc', {'name':'jack'}]);">传递数组到OC</h5>
        <h5 style="color:blue" onclick="method.dictTest({'name':'jack', 'data':[1, 'hello', {'age' : 10}]});">传递字典到OC</h5>
        <h5 style="color:blue" onclick="DictionaryFun(method.returnDict());">从OC返回字典</h5>
        <h5 style="color:blue" onclick="ArrayFun(method.returnArray());">从OC返回数组</h5>
    </body>
    
</html>
上一篇 下一篇

猜你喜欢

热点阅读