zoukankan      html  css  js  c++  java
  • iOS开发-基于原生JS与OC方法互相调用并传值(附HTML代码)

    最近项目里面有有个商品活动界面,要与web端传值,将用户在网页点击的商品id 传给客户端,也就是js交互,其实再说明白一点就是方法的互相调用而已。

    本文叙述下如何进行原生的JavaScript交互

    本文包括JS调用OC方法并传值,OC调用JS方法并传值

    本来想把html放进服务器里面,然后访问,但是觉得如果html在本地加载更有助于理解,特把html放进项目里

    HTML代码

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. </head>
    6. <body>
    7. <div style="margin-top: 20px">
    8. <h2>JS与OC交互</h2>
    9. <input type="button" value="唤起本地方法(call)" onclick="tianbai.call()">
    10. </div>
    11. <div>
    12. <input type="button" value="唤起getCall:(NSString *)callString传值" onclick="call()">
    13. </div>
    14.  
    15. <script>
    16.  
    17.  
    18.  
    19. var call = function()
    20. {
    21. var callInfo = JSON.stringify({"jianshu": "http://www.jianshu.com/users/55c8fdc3c6e7/latest_articles"});
    22. tianbai.getCall(callInfo);
    23. }
    24.  
    25. var Callback = function(str)
    26. {
    27. alert(str);
    28. }
    29. var alerCallback = function()
    30. {
    31. alert('成功');
    32. }
    33. </script>
    34. </body>
    35. </html>

    上面html的代码:建立了两个button

    第一个button绑定了 tianbai.call() 方法,这里 tianbai 是一个对象,这个对象的作用下面OC代码中会说明, tianbai.call() 代表 tianbai 对象调用 call() 方法

    第二个button绑定了 call() 的方法,调用的是下面JavaScript中的 call() 方法,在 JavaScript 的 call() 里面,定义一个 callInfo 参数,方法中 tianbai.getCall(callInfo) 代表 tianbai 对象调用 getCall 方法并传参数 callInfo ,下面两个方法是OC调用JavaScript方法,其中Callback传回str,alerCallback为OC仅调用JavaScript方法!

    OC代码

    demo采用原生的JavaScriptCore类

    引入三个名词:

    1. JSContext:给JavaScript提供运行的上下文环境
    2. JSValue:JavaScript和Objective-C数据和方法的桥梁
    3. JSExport:这是一个协议,如果采用协议的方法交互,自己定义的协议必须遵守此协议

    ViewController.h中的代码(代码过长,方法说明都在注释里)

    1. #import <UIKit/UIKit.h>
    2. //导入头文件
    3. #import <JavaScriptCore/JavaScriptCore.h>
    4.  
    5. @protocol JSObjcDelegate <JSExport>
    6. //tianbai对象调用的JavaScript方法,必须声明!!!
    7. - (void)call;
    8. - (void)getCall:(NSString *)callString;
    9.  
    10. @end
    11. @interface ViewController : UIViewController<UIWebViewDelegate,JSObjcDelegate>
    12. @property (nonatomic, strong) JSContext *jsContext;
    13. @property (strong, nonatomic) UIWebView *webView;
    14.  
    15. @end

    ViewController.m中的代码(代码过长,方法说明都在注释里)

    JavaScriptCore中web页面调用原生应用的方法可以用Delegate或Block两种方法,此文以按Delegate讲解。

    设置webView

    1. self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 20, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
    2. self.webView.delegate = self;
    3. //从本地加载html文件
    4. NSString* path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    5. NSURL* url = [NSURL fileURLWithPath:path];
    6. NSURLRequest* request = [NSURLRequest requestWithURL:url] ;
    7. [self.webView loadRequest:request];
    8.  
    9. [self.view addSubview:self.webView];

    JavaScript的tianbai是一个对象,充当原生应用和web页面之间的一个桥梁。用来调用方法

    webview加载完成调用代理

    1. - (void)webViewDidFinishLoad:(UIWebView *)webView {
    2.  
    3. // 设置javaScriptContext上下文
    4. self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    5. //将tianbai对象指向自身
    6. self.jsContext[@"tianbai"] = self;
    7. self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
    8. context.exception = exceptionValue;
    9. NSLog(@"异常信息:%@", exceptionValue);
    10. };
    11. }

    将对象指向自身后,如果调用 tianbai.call() 会响应下面的方法,OC方法中调用js中的Callback方法,并传值

    1. - (void)call{
    2. NSLog(@"call");
    3. // 之后在回调JavaScript的方法Callback把内容传出去
    4. JSValue *Callback = self.jsContext[@"Callback"];
    5. //传值给web端
    6. [Callback callWithArguments:@[@"唤起本地OC回调完成"]];
    7. }

    将对象指向自身后,如果调用 tianbai.getCall(callInfo) 会响应下面的方法,OC方法中仅调用JavaScript中的alerCallback方法

    1. - (void)getCall:(NSString *)callString{
    2. NSLog(@"Get:%@", callString);
    3. // 成功回调JavaScript的方法Callback
    4. JSValue *Callback = self.jsContext[@"alerCallback"];
    5. [Callback callWithArguments:nil];
    6. }

    将对象指向自身后,还可以向html注入js

    1. - (void)alert{
    2.  
    3. // 直接添加提示框
    4. NSString *str = @"alert('OC添加JS提示成功')";
    5. [self.jsContext evaluateScript:str];
    6.  
    7. }

    Demo地址:https://github.com/QuTianbai/JavaScript

  • 相关阅读:
    从Ecma规范深入理解js中的this的指向
    js中继承的几种用法总结(apply,call,prototype)
    缓存 Array.length 是老生常谈的小优化
    spark app
    source code spark
    spark dev by IDEA
    编译spark-0.9.1
    图解GIT,ZT
    Spark分布式安装
    倒排索引(Inverted Index)
  • 原文地址:https://www.cnblogs.com/Yishu/p/9361002.html
Copyright © 2011-2022 走看看