OC与JS交互小结,JSON字符串传递规范

        这套协议在OC的Webview里面主要采用delegate的写法,一般与前端交互不使用第三方框架的情况下,JS给OC传值基本存在三种交互协议,但是每种协议都是需要和前端人员确认好方法名,两边要保持一致。 

 JS给OC传值,并调用OC方法 

        1.使用delegate的方式交互,此种方法在iOS7之后提出,通过JavaScriptCore这个框架进行交互,具体的代码在文后给出或者看代码。此种方法有一些需要注意的点,例如

-(NSString *)appVersion:(JSValue *)version{

         return"someThing";

 } 


在网上的一些文章中基本没有提到可以设置返回值,在这个方法里面可以直接return返回值,为同步回调。前端回传的参数类型为JSValue类型,如要解析,需要使用JSValue的toString方法,然后再转为NSDictionary即可。如果不定义接收参数其实使用delegate这种方式也是可以接收的,代码如下        

NSArray *arg = [JSContext currentArguments]; 

 JSValue *resouce = arg.firstObject; 

 此种情况适用于前端需要回传多个参数,但是写法又不能和安卓的冲突的时候。在delegate里面需要注意的还有这些代理方法都是出于子线程的,Xcode9增加了自动检测线程,注意线程问题。 

       2.使用Block进行交互,此种方法比较方便简洁, OC核心代码:

 - (void)webViewDidFinishLoad:(UIWebView *)webView{ 

   JSContext *context = [webView   valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; 

 context[@"passValue"] = ^{ 

 NSArray *arg = [JSContext currentArguments]; 

 for (id obj in arg) { 

 NSLog(@"%@", obj); 

 } };

 } 

 JS核心代码是 

      function testClick() {

     var str1=document.getElementById("text1").value;

     var str2=document.getElementById("text2").value; 

      passValue(str1,str2); 

 } 

      注意:此代码需要放在webViewDidFinishLoad里面,这种方法应该是不可以设置前缀的

 3.使用拦截协议,两方定好协议头,如果传过来的协议头符合就做相应的处理,多用于页面按钮的一些跳转事件,比如点击客户咨询,跳转到原生的客户咨询界面。 

 JS代码:

 function testClick() { 

      var str1=document.getElementById("text1").value;

      var str2=document.getElementById("text2").value;

        // "objc://"为自定义协议头; // str1&str2为要传给OC的值,以":/"作为分隔                       window.location.href="objc://"+":/"+str1+":/"+str2; 

 } 

 在需要给OC传值的函数里(例如:testClick())写如上格式的代码 

 OC代码:

 //遵守UIWebViewDelegate代理协议。

 -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 

 //拿到网页的实时url NSString *requestStr = [[request.URL absoluteString] stringByRemovingPercentEncoding]; /

/在url中寻找自定义协议头"objc://" 

 // 格式 objc://loadUrl/blog.csdn.net 协议/方法/网址 

 //判断链接中的协议头,如果是objc://, 则进行相关操作

 if ([requestStr hasPrefix:@"objc://"]) { 

 //拿到除去协议头的后部 NSString *urlContent = [urlStr substringFromIndex:[@"objc://" length]]; NSLog(@"%@", urlContent); //用/来拆分字符串 

 NSArray *urls = [urlContent componentsSeparatedByString:@"/"]; 

 NSLog(@"拆分的结果为:%@", urls); 

 //怕重复可以多定义一个头aaa,也可省略

 if ([@"aaa.toChat" isEqualToString:urls[0]]){ 

 [self pushChatView];

 }

 return NO; 

 } 

 return YES; 

 } 

 -(void)pushChatView{ 

 //具体业务代码

 } 

 OC调用JC方法并传值:

  [_webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"window.sendOCData&&window.sendOCData('%@')",parameter]];

 parameter是需要传递的值,建议为JSON字符串,注意%@外面是一个单引号,另外传递给JSON的字符串不要使用自动换行方法encode,先把NSDictionary转为NSData再转为NSString,代码如下 

 NSData *paramsJsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:nil]; //NSJSONWritingPrettyPrinted不要使用这些加了自动换行的,不然 前端无法接收 

 NSString * paramsStr = [[NSString alloc] initWithData:paramsJsonData encoding:NSUTF8StringEncoding]; 

 还有如果项目中即用了delegate又使用拦截协议,而且定义的协议头一样,那么会首先执行delegate的,拦截协议无法生效,所以如果需要使用两种,那么请定义不同的协议头。 

参考网址: 

http://blog.csdn.net/leaderqiu/article/details/51955956 http://www.cnblogs.com/yueyuanyueyuan/p/5651266.html 

 http://www.cocoachina.com/cms/wap.php?action=article&id=15105 http://blog.csdn.net/u012963325/article/details/51134574 

http://www.jianshu.com/p/063d748e072d

 delegate的主要代码 OC代码:

#import "ViewController.h"

#import JavaScriptCore/JavaScriptCore.h 尖括号

@protocol JSObjcDelegate

- (void)callCamera;

- (void)share:(NSString *)shareString;

@end

@interface ViewController () UIWebViewDelegate,JSExport 尖括号

@property (nonatomic, strong) JSContext *jsContext;

@property (strong, nonatomic) UIWebView *webView;

@end@implementation ViewController

#pragma mark - Life Circle

- (void)viewDidLoad {

 [super viewDidLoad]; 

 self.webView = [[UIWebView alloc]initWithFrame:self.view.bounds];

 [self.view addSubview:self.webView]; 

 self.webView.userInteractionEnabled = YES; 

 NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"]; self.webView.delegate = self; [self.webView loadRequest:[[NSURLRequest alloc] initWithURL:url]]; 

 }

#pragma mark - UIWebViewDelegate

- (void)webViewDidFinishLoad:(UIWebView *)webView { 

 __weak typeof(self) weakSelf = self; self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; 

 self.jsContext[@"Toyun"] = self; 

 self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { 

 context.exception = exceptionValue;

 NSLog(@"异常信息:%@", exceptionValue

);

 }; 

 }

#pragma mark - JSObjcDelegate

- (void)callCamera { 

 NSLog(@"callCamera"); // 获取到照片之后在回调js的方法picCallback把图片传出去 JSValue *picCallback = self.jsContext[@"picCallback"]; 

 [picCallback callWithArguments:@[@"photos"]];

}

- (void)share:(NSString *)shareString { 

 NSLog(@"share:%@", shareString); // 分享成功回调js的方法shareCallback JSValue *shareCallback = self.jsContext[@"shareCallback"]; 

 [shareCallback callWithArguments:nil];

}

@end

JS代码:

Objective-C和JavaScript交互的那些事

var callShare = function() {

var shareInfo = JSON.stringify({"title": "标题", "desc": "内容", "shareUrl": "http://www.jianshu.com/p/f896d73c670a",

"shareIco":"http://upload-images.jianshu.io/upload_images/1192353-fd26211d54aea8a9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"});

Toyun.share(shareInfo);

}

var picCallback = function(photos) {

alert(photos);

}

var shareCallback = function(){

alert('success');

}

能力有限有错误的话请指出,谢谢,排版是直接先在公司的worktile上先写再复制过来的,各位勉强看吧

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,478评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,825评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,482评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,726评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,633评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,018评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,168评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,320评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,264评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,288评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,995评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,587评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,909评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,284评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,862评论 2 339

推荐阅读更多精彩内容

  • 随着H5技术的兴起,在iOS开发过程中,难免会遇到原生应用需要和H5页面交互的问题。其中会涉及方法调用及参数传值等...
    Chris_js阅读 3,050评论 1 8
  • OC与JS交互之JavaScriptCore 本文摘抄自:https://hjgitbook.gitbooks.i...
    大冲哥阅读 1,016评论 0 1
  • 前言 ObjectiveC与Js交互是常见的需求,可对于新手或者所谓的高手而言,其实并不是那么简单明了。这里只介绍...
    一路向北客阅读 364评论 0 4
  • 本教程中所涉及到的几种类型: JSContext, JSContext是代表JS的执行环境,通过-evaluate...
    贝勒老爷阅读 846评论 0 5
  • 跟原生开发相比,H5的开发相对来一个成熟的框架和团队来讲在开发速度和开发效率上有着比原生很大的优势,至少不用等待审...
    大冲哥阅读 1,822评论 0 7