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.lxweimin.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.lxweimin.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閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容

  • 隨著H5技術的興起,在iOS開發過程中,難免會遇到原生應用需要和H5頁面交互的問題。其中會涉及方法調用及參數傳值等...
    Chris_js閱讀 3,104評論 1 8
  • OC與JS交互之JavaScriptCore 本文摘抄自:https://hjgitbook.gitbooks.i...
    大沖哥閱讀 1,027評論 0 1
  • 前言 ObjectiveC與Js交互是常見的需求,可對于新手或者所謂的高手而言,其實并不是那么簡單明了。這里只介紹...
    一路向北客閱讀 367評論 0 4
  • 本教程中所涉及到的幾種類型: JSContext, JSContext是代表JS的執行環境,通過-evaluate...
    貝勒老爺閱讀 879評論 0 5
  • 跟原生開發相比,H5的開發相對來一個成熟的框架和團隊來講在開發速度和開發效率上有著比原生很大的優勢,至少不用等待審...
    大沖哥閱讀 1,858評論 0 7