1. 程式人生 > >iOS與JS互動Demo文件(ObjC版)

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中暴露出來,才能呼叫
Objc與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


相關推薦

iOSJS互動DemoObjC

參考原文連結: http://mp.weixin.qq.com/s?__biz=MzIzMzA4NjA5Mw==&mid=214063688&idx=1&sn=903258ec2d3ae431b4d9ee55cb59ed89#rd http://ww

AKKAjava——用例部署場景

我如何使用與部署akka? 有兩種不同的使用akka的方式: 作為一個庫:作為一個web應用的類路徑下的普通JAR使用,將它放在WEB-INF/lib。 在一上主類中通過例項化ActorSystem作為一個獨立的應用執行,或使用微核心(Scala) / 將akka作為一個庫使用 如果你在

徵求意見稿中國銀河證券公募基金分類體系規則 2019

(徵求意見稿)中國銀河證券公募基金分類體系規則文件 (2019版) 銀河證券基金研究中心 4天前 備註說明:2019版基金分類體系(徵求意見稿)從2018年12月5日開始進行一個月的徵求意見,歡迎基金行業各方推出寶貴意見。2019年1月5日與6日(週末)切換到2019版分類體系並進行各種

AKKAjava—角色

升級 Akka支援在執行時對角色訊息迴圈 (例如它的的實現)進行實時替換: 在角色中呼叫getContext.become 方法。 熱替換的程式碼被存在一個棧中,可以被pushed(replacing 或 adding 在頂部)和popped。 注意:請注意角色被其監管者重啟後將恢復其最初的行為。 熱替換角

AKKAjava

目前我正在翻譯AKKA官網文件。翻譯:吳京潤 譯者注:本人正在翻譯AKKA官網文件,本篇是文件第一章,歡迎有興趣的同學加入一起翻譯。 1.    介紹 2.   綜述        2.1   術語,概念        2.2   角色系統        2.3   什麼是角色

AKKAjava——什麼是AKKA?

可擴充套件的實時事務處理 我們相信編寫併發、容錯、可擴充套件的應用相當的困難。蓋因大多數時候我們一直在使用錯誤的工具和錯誤的抽象等級。AKKA就是為了改變這一切的。我們利用角色模型提升了抽象等級,並且提供了一個用來構建可擴充套件的、彈性的以及響應式應用的更好的平臺——更多資訊請見Reacti

AKKAjava——hello world

本教程說明了通用啟動器類akka.Main,只接收一個命令列引數:應用的主actor類名。這個main方法將為執行actor建立基礎設施,用來啟動指定的主actor以及在主actor終止時為關閉整個應用做出安排

AKKAJAVA—派發器

更多派發器配置例子 配置PinnedDispatcher: my-pinned-dispatcher { executor = "thread-pool-executor" type = PinnedDispatcher } 接著使用它: ActorRef myActor = system

Akkajava-為什麼選擇Akka

1.2 為什麼選擇Akka? 1.2.1 與同類其它產品相比,Akka平臺有什麼過人之處呢? Akka 提供可伸縮的實時事務處理能力。 Akka在以下方面提供了一致的執行時和程式設計模型: 縱向擴充套件性(併發) 橫向擴充套件性(遠端呼叫) 容錯性 由於Akka的高內聚性和連貫的語義,學

AKKAjava—位置透明性

2.6 位置透明性 前一章節描述瞭如何使用角色路徑來實現位置透明性。這一個特性應該需要一些額外的說明,因為與之關聯的術語“transparent remoting”(透明的遠端處理)在程式語言、平臺和技術中的用法是不一樣的。 2.6.1 預設分散式 Akka中的所有事物被設計成用於分散式環境

AKKAjava——準備開始

預備知識 AKKA要求你的計算機已經安裝了Java1.6或更高版本。 入門指南與模板專案 學習AKKA的最好方式是下載Typesafe Activator並嘗試一個AKKA模板專案。 下載 有許多種下載AKKA的方式。你可以把它當作Typesafe平臺的一部分下載(就像上面描述的)。還可以下

AKKAjava—什麼是角色

原文: 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,很多時候大家不知道怎麽正確的查看填寫。下面介紹下如何得到正確配置。 一、正確獲得證書“

iOSJS互動的4種方法

iOS與JS互動的方法: 1.攔截url(適用於UIWebView和WKWebView) 2.JavaScriptCore(只適用於UIWebView,iOS7+) 3.WKScriptMessageHandler(只適用於WKWebView,iOS8+) 4.WebViewJ

Swift WKWebView(二):iOSjs互動

在上一篇中我們介紹了Swift下WKWebView的基本使用方法,下面總結一下iOS與js互動的實現,最終的頁面效果如下圖所示: 其中,js有關程式碼如下: function navButtonAction(name,age){

目前iOSJS互動的方法選擇比對

只是針對目前存在的互動方式做個比對。不會涉及任何實現。如需知道具體的使用。可自行baidu或者Google。 攔截協議 攔截協議是最簡單的互動方式,在Android端和iOS端直接攔截,可以統一web前端的程式碼。web前端通過在連結中帶上引數。比如: 88gongxiang:

iOSjs互動(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