iOS與JS互動Demo文件(ObjC版)
參考原文連結:
http://mp.weixin.qq.com/s?__biz=MzIzMzA4NjA5Mw==&mid=214063688&idx=1&sn=903258ec2d3ae431b4d9ee55cb59ed89#rd
http://www.cocoachina.com/ios/20160127/15105.html
本文介紹:iOS7.0後出來的JavaScriptCore framework的使用。
關於:JavaScriptCore
涉及到的幾種型別。
- JSContext, JSContext是代表JS的執行環境,通過-evaluateScript:方法就可以執行一JS程式碼
- JSValue, JSValue封裝了JS與ObjC中的對應的型別,以及呼叫JS的API等
- JSExport, JSExport是一個協議,遵守此協議,就可以定義我們自己的協議,在協議中宣告的API都會在JS中暴露出來,才能呼叫
1:通過網頁擷取
2:在Objc中通過JSContext注入模型,然後呼叫模型的方法。
以下是大神標哥寫的例子,可以總結為以下五個互動場景。
開始編寫:
1:通過注入模型的方式互動
首先,我們需要先定義一個協議,而且這個協議必須要遵守JSExport協議。
@protocol JavaScriptObjectiveCDelegate <JSExport> // JS呼叫此方法來呼叫OC的系統相簿方法 - (void)callSystemCamera; // 在JS中呼叫時,函式名應該為showAlertMsg(arg1, arg2) // 這裡是只兩個引數的。 - (void)showAlert:(NSString *)title msg:(NSString *)msg; // 通過JSON傳過來 - (void)callWithDict:(NSDictionary *)params; // JS呼叫Oc,然後在OC中通過呼叫JS方法來傳值給JS。 - (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params; @end
接下來,我們還需要定義一個模型:
// 此模型用於注入JS的模型,這樣就可以通過模型來呼叫方法。
@interface HYBJsObjCModel : NSObject <JavaScriptObjectiveCDelegate>
@property (nonatomic, weak) JSContext *jsContext;
@property (nonatomic, weak) UIWebView *webView;
@end
實現這個模型:
@implementation HYBJsObjCModel - (void)callWithDict:(NSDictionary *)params { NSLog(@"Js呼叫了OC的方法,引數為:%@", params); } // Js呼叫了callSystemCamera - (void)callSystemCamera { NSLog(@"JS呼叫了OC的方法,調起系統相簿"); // JS呼叫後OC後,又通過OC呼叫JS,但是這個是沒有傳引數的 JSValue *jsFunc = self.jsContext[@"jsFunc"]; [jsFunc callWithArguments:nil]; } - (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params { NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params); // 呼叫JS的方法 JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"]; [jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]]; } - (void)showAlert:(NSString *)title msg:(NSString *)msg { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *a = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [a show]; }); } @end
接下來,我們在controller中在webview載入完成的代理中,給JS注入模型。
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 通過模型呼叫方法,這種方式更好些。
HYBJsObjCModel *model = [[HYBJsObjCModel alloc] init];
self.jsContext[@"OCModel"] = model;
model.jsContext = self.jsContext;
model.webView = self.webView;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"異常資訊:%@", exceptionValue);
};
}
我們是通過webView的valueForKeyPath獲取的,其路徑為documentView.webView.mainFrame.javaScriptContext
。
這樣就可以獲取到JS的context,然後為這個context注入我們的模型物件。
我們先寫兩個JS方法:
var jsFunc = function() {
alert('Objective-C call js to show alert');
}
var jsParamFunc = function(argument) {
document.getElementById('jsParamFuncSpan').innerHTML
= argument['name'];
}
這裡我們定義了兩個JS方法,一個是jsFunc,不帶引數。
另一個是jsParamFunc,帶一個引數。
接下來,我們在html中的body中新增以下程式碼:
<div style="margin-top: 100px">
<h1>Test how to use objective-c call js</h1>
<input type="button" value="Call ObjC system camera" onclick="OCModel.callSystemCamera()">
<input type="button" value="Call ObjC system alert" onclick="OCModel.showAlertMsg('js title', 'js message')">
</div>
<div>
<input type="button" value="Call ObjC func with JSON " onclick="OCModel.callWithDict({'name': 'testname', 'age': 10, 'height': 170})">
<input type="button" value="Call ObjC func with JSON and ObjC call js func to pass args." onclick="OCModel.jsCallObjcAndObjcCallJsWithDict({'name': 'testname', 'age': 10, 'height': 170})">
</div>
<div>
<span id="jsParamFuncSpan" style="color: red; font-size: 50px;"></span>
</div>
現在就可以測試程式碼了。
當我們點選第一個按鈕:Call
ObjC system camera
時,
通過OCModel.callSystemCamera()
,就可以在HTML中通過JS呼叫OC的方法。
在OC程式碼中,我們的callSystemCamera
方法體中,添加了以下兩行程式碼,就是獲取HTML中所定義的JS就去jsFunc,然後呼叫它。
JSValue *jsFunc = self.jsContext[@"jsFunc"];
[jsFunc callWithArguments:nil];
這樣就可以在JS呼叫OC方法時,也讓OC反饋給JS。
看看下面傳字典引數:
- (void)jsCallObjcAndObjcCallJsWithDict:(NSDictionary *)params {
NSLog(@"jsCallObjcAndObjcCallJsWithDict was called, params is %@", params);
// 呼叫JS的方法
JSValue *jsParamFunc = self.jsContext[@"jsParamFunc"];
[jsParamFunc callWithArguments:@[@{@"age": @10, @"name": @"lili", @"height": @158}]];
}
獲取我們在HTML中定義的jsParamFunc方法,然後呼叫它並傳了一個字典作為引數。
好了,就講這麼多吧,如果想要Demo原始碼,請到
github:https://github.com/CoderJackyHuang/IOSCallJsOrJsCallIOS
想學習Swift版的?請閱讀:
http://mp.weixin.qq.com/s?__biz=MzIzMzA4NjA5Mw==&mid=214070747&idx=1&sn=57b45fa293d0500365d9a0a4ff74a4e1#rd
相關推薦
iOS與JS互動Demo文件(ObjC版)
參考原文連結: http://mp.weixin.qq.com/s?__biz=MzIzMzA4NjA5Mw==&mid=214063688&idx=1&sn=903258ec2d3ae431b4d9ee55cb59ed89#rd http://ww
AKKA文件(java版)——用例與部署場景
我如何使用與部署akka? 有兩種不同的使用akka的方式: 作為一個庫:作為一個web應用的類路徑下的普通JAR使用,將它放在WEB-INF/lib。 在一上主類中通過例項化ActorSystem作為一個獨立的應用執行,或使用微核心(Scala) / 將akka作為一個庫使用 如果你在
(徵求意見稿)中國銀河證券公募基金分類體系規則文件 (2019版)
(徵求意見稿)中國銀河證券公募基金分類體系規則文件 (2019版) 銀河證券基金研究中心 4天前 備註說明:2019版基金分類體系(徵求意見稿)從2018年12月5日開始進行一個月的徵求意見,歡迎基金行業各方推出寶貴意見。2019年1月5日與6日(週末)切換到2019版分類體系並進行各種
AKKA文件(java版)—角色
升級 Akka支援在執行時對角色訊息迴圈 (例如它的的實現)進行實時替換: 在角色中呼叫getContext.become 方法。 熱替換的程式碼被存在一個棧中,可以被pushed(replacing 或 adding 在頂部)和popped。 注意:請注意角色被其監管者重啟後將恢復其最初的行為。 熱替換角
AKKA文件(java版)
目前我正在翻譯AKKA官網文件。翻譯:吳京潤 譯者注:本人正在翻譯AKKA官網文件,本篇是文件第一章,歡迎有興趣的同學加入一起翻譯。 1. 介紹 2. 綜述 2.1 術語,概念 2.2 角色系統 2.3 什麼是角色
AKKA文件(java版)——什麼是AKKA?
可擴充套件的實時事務處理 我們相信編寫併發、容錯、可擴充套件的應用相當的困難。蓋因大多數時候我們一直在使用錯誤的工具和錯誤的抽象等級。AKKA就是為了改變這一切的。我們利用角色模型提升了抽象等級,並且提供了一個用來構建可擴充套件的、彈性的以及響應式應用的更好的平臺——更多資訊請見Reacti
AKKA文件(java版)——hello world
本教程說明了通用啟動器類akka.Main,只接收一個命令列引數:應用的主actor類名。這個main方法將為執行actor建立基礎設施,用來啟動指定的主actor以及在主actor終止時為關閉整個應用做出安排
AKKA文件(JAVA版)—派發器
更多派發器配置例子 配置PinnedDispatcher: my-pinned-dispatcher { executor = "thread-pool-executor" type = PinnedDispatcher } 接著使用它: ActorRef myActor = system
Akka文件(java版)-為什麼選擇Akka
1.2 為什麼選擇Akka? 1.2.1 與同類其它產品相比,Akka平臺有什麼過人之處呢? Akka 提供可伸縮的實時事務處理能力。 Akka在以下方面提供了一致的執行時和程式設計模型: 縱向擴充套件性(併發) 橫向擴充套件性(遠端呼叫) 容錯性 由於Akka的高內聚性和連貫的語義,學
AKKA文件(java版)—位置透明性
2.6 位置透明性 前一章節描述瞭如何使用角色路徑來實現位置透明性。這一個特性應該需要一些額外的說明,因為與之關聯的術語“transparent remoting”(透明的遠端處理)在程式語言、平臺和技術中的用法是不一樣的。 2.6.1 預設分散式 Akka中的所有事物被設計成用於分散式環境
AKKA文件(java版)——準備開始
預備知識 AKKA要求你的計算機已經安裝了Java1.6或更高版本。 入門指南與模板專案 學習AKKA的最好方式是下載Typesafe Activator並嘗試一個AKKA模板專案。 下載 有許多種下載AKKA的方式。你可以把它當作Typesafe平臺的一部分下載(就像上面描述的)。還可以下
AKKA文件(java版)—什麼是角色
原文: http://doc.akka.io/docs/akka/2.3.5/general/actors.html 譯者:Vitas 2.3 什麼是角色? 前面角色系統一節介紹了一群角色如何形成一個層次結構,並且介紹了角色是構建應用程式的最小單位。本節我們將角色拿出來單獨介紹,解釋一些你在使
grunt 合並壓縮js和css文件(二)
1.0 ajax depend cnp com .html post tle runt 具體node及文件配置請看: grunt 安裝使用(一) 要壓縮的文件 --src/ ajax.js assets.js touch.js zepto.js
js上傳文件(圖片)限制格式及大小為3M
max element 不能 jpg script 圖片大小 -s 打開 -1 本文保存為.html文件用瀏覽器打開即可測試功能 <form id="form1" name="form1" method="post" action="" enctype="m
證書(Certificate)與描述文件(Provisioning Profiles)
itl 下載證書 html library com x509 highlight 重新 app id 在使用腳本xcodebuild自動打包的時候,會用到簽名證書和描述文件的UUID,很多時候大家不知道怎麽正確的查看填寫。下面介紹下如何得到正確配置。 一、正確獲得證書“
iOS與JS互動的4種方法
iOS與JS互動的方法: 1.攔截url(適用於UIWebView和WKWebView) 2.JavaScriptCore(只適用於UIWebView,iOS7+) 3.WKScriptMessageHandler(只適用於WKWebView,iOS8+) 4.WebViewJ
Swift WKWebView(二):iOS與js互動
在上一篇中我們介紹了Swift下WKWebView的基本使用方法,下面總結一下iOS與js互動的實現,最終的頁面效果如下圖所示: 其中,js有關程式碼如下: function navButtonAction(name,age){
目前iOS與JS互動的方法選擇比對
只是針對目前存在的互動方式做個比對。不會涉及任何實現。如需知道具體的使用。可自行baidu或者Google。 攔截協議 攔截協議是最簡單的互動方式,在Android端和iOS端直接攔截,可以統一web前端的程式碼。web前端通過在連結中帶上引數。比如: 88gongxiang:
iOS與js互動(WebView+WKWebView)
需求:1點選js登入按鈕將使用者賬號和密碼傳給移動端 2將客戶端的token傳給html端 據我瞭解有以下幾種方法 1:webview的javascriptCore 2:webkit 3:url攔截 4:第三方庫 我用的是1和2
iOS 與Js 互動崩潰原因
iOS 與 Js 互動時 關於 UI 介面的跳轉的時候 他會自動開闢子執行緒 我們要把他放在主執行緒中 dispatch_async(dispatch_get_main_queue(), ^{ [self.navigationControll