iOS webView的高階用法之JS互動,js與oc的相互呼叫(JavaScriptCore)
重要的事情放前面 github地址:https://github.com/horisea/JSCallOCTest 歡迎star
前言:說起JS互動,很多童鞋會黯然色變,感覺很高深的樣子。大部分小夥伴只知道一種,哪一種我也說說吧。
1.在webView中將要請求的時候,攔截URL,進行重定向,然而該場景實用有限,網上資料也很多下面說說另一種互動方式。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
2.先說一下這種互動方式應用的場景吧。
2.1:需求:假如貴公司在做一個金融專案,有一個版本功能需要提交個人資料資訊,只是為了一個業務需要,那麼通過h5做一套,然後iOS和Android只需要webView載入就行,明顯提高了開發效率。。。如果貴公司的其他產品也想接入這個功能,那也能通過webview方式直接用了,所謂是牛逼哄哄,通用性特別強。
但是:(1):比如,webview裡有一個上傳身份證照片的功能,點選網頁,需要iOS端調起相簿功能。。如何互動??
(2): 載入的網頁中,點選一個按鈕,要檢視訂單詳情功能,但是需要傳會訂單號,怎麼辦:
(3): 點選下一步,,iOS端進入下一個介面;??
這就牽扯到JS呼叫OC方法,傳遞引數等等。
3.本文將非常詳細的說明使用方法,一句程式碼不少的說明,你只需要按照步驟操作,一定能執行出你想要的JS互動場景,包你能派上大用場。。廢話不說了,開始吧
正文:JS互動,就是js 中通過一個物件來呼叫方法的
1.js互動,首先我們要準備一個html檔案,沒有網頁檔案,要不然怎麼互動:至於這些東西怎麼建立,這裡不做介紹,樓主最後會附上聯絡方式,提供demo,demo中有,直接複製就行。
1.1.首先準備一個html檔案,html檔案裡引用了外部的JS檔案
2.js檔案,裡面實現了html檔案裡的一些按鈕的點選事件
圖片裡非常清楚的註釋了一些重要程式碼的註釋,非常詳細,搞得自己很會h5一樣,程式設計師,不能放棄任何一次裝b的機會,
⚠️注意: 這裡在網頁中寫了4個按鈕,,分別調OC的方法
1. 點選按鈕,喚起系統相簿功能;
2. 就是簡單的調一個方法
3. 呼叫一個引數的方法
4. 呼叫多個引數的方法,這裡舉例是兩個。
2.首先建立一個類 繼承NSObject ,並且規定一個協議,直接上程式碼
2.1>建立TestJSObject.h標頭檔案
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
@protocol TestJSObjectProtocol <JSExport>
/// 調支付
- (void)ZTHpay;
/// 調系統相簿
- (void)ZTHShowPicker;
/// 傳引數回來 比如是一個訂單號
- (void)ZTHPassParameter:(NSString *)orderNumber;
/// 傳兩個引數回來 比如是訂單號,姓名
- (void)ZTHTestParameteroneAnd:(NSString *)orderNumber Parametertwo:(NSString *)name;
@end
@interface TestJSObject : NSObject<TestJSObjectProtocol>
///定義三種block,回撥到控制器中;
@property (nonatomic,copy)void(^showPickerBlock)();
@end
2.2:然後在.m中實現宣告的方法,這4個方法,都會被呼叫
#import "TestJSObject.h"
@implementation TestJSObject
- (void)ZTHpay{
NSLog(@"調了支付了-----------------");
}
- (void)ZTHShowPicker{
NSLog(@"調了相機-------------------");
dispatch_async(dispatch_get_main_queue(), ^{
//當然回撥後要處理的邏輯,肯定不能在這個類裡處理,這裡採用block回撥到控制器中處理,其餘的三種方式都可以用這種方式處理,這裡就不一一列舉了
self.showPickerBlock();
});
}
- (void)ZTHPassParameter:(NSString *)orderNumber{
NSLog(@"%@", orderNumber);
}
//- (void)ZTHTestParameterone:(NSString *)orderNumber AndParametertwo:(NSString *)name{
// NSLog(@"訂單號--%@姓名---%@", orderNumber, name);
//}
- (void)ZTHTestParameteroneAnd:(NSString *)orderNumber Parametertwo:(NSString *)name{
NSLog(@"訂單號--%@姓名---%@", orderNumber, name);
}
@end
3最後在控制器中
3.1>在懶載入中,設定了web view的url,是一個本地檔案,也就是我們一開始寫的html檔案的路徑。
#pragma mark - lazy
- (UIWebView *)webview{
if (!_webview) {
_webview=[[UIWebViewalloc]initWithFrame:CGRectMake(0,200,self.view.bounds.size.width,300)];
_webview.delegate =self;
_webview.backgroundColor=[UIColorlightGrayColor];
NSString *htmlPath = [[NSBundlemainBundle]pathForResource:@"index"ofType:@"html"];
NSURL *localUrl = [[NSURLalloc]initFileURLWithPath:htmlPath];
[_webview loadRequest:[NSURLRequestrequestWithURL:localUrl]];
}
return _webview;
}
3.2.
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView{
//首先建立JSContext物件(此處通過當前webView的鍵獲取到jscontext)
_context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//第二種情況,js是通過物件呼叫的,我們假設js裡面有一個物件 testobject 在呼叫方法
//首先建立我們新建類的物件,將他賦值給js的物件
TestJSObject *testJO=[TestJSObjectnew];
testJO.showPickerBlock = ^{
[selfshowImagePicker];
};
_context[@"testobject"]=testJO;
}
到這裡,就已經大功告成了。。。文中打紅色的文字部分需要您仔細欣賞欣賞,,首先在TestJSObject.h中,我們聲明瞭一個block屬性,原因JS呼叫的方法實現在改類中,但是我們不能在這個類裡處理邏輯,那當然需要一個屬性回撥到控制器中咯,於是在實現中呼叫了block,然後在上面寫了block的實體,去呼叫
showImagePicker方法,然後你就可以處理了,,,,其實就是block最簡單的用法,,但是,,肯定有很多童鞋不瞭解。。哈哈,不耽誤。。下面附上控制器的所有程式碼,
// Copyright © 2016年朱同海. All rights reserved.
// 本文主要介紹JS呼叫OC互動的方式
#import "ViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
#import "TestJSObject.h"
@interface ViewController () <UIWebViewDelegate,UIActionSheetDelegate>
{
JSContext *_context;
}
@property (nonatomic,strong)UIWebView *webview;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColorcyanColor];
[self.viewaddSubview:self.webview];
}
#pragma mark - lazy
- (UIWebView *)webview{
if (!_webview) {
_webview=[[UIWebViewalloc]initWithFrame:CGRectMake(0,200,self.view.bounds.size.width,300)];
_webview.delegate =self;
_webview.backgroundColor=[UIColorlightGrayColor];
NSString *htmlPath = [[NSBundlemainBundle]pathForResource:@"index"ofType:@"html"];
NSURL *localUrl = [[NSURLalloc]initFileURLWithPath:htmlPath];
[_webview loadRequest:[NSURLRequestrequestWithURL:localUrl]];
}
return _webview;
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView{
//首先建立JSContext物件(此處通過當前webView的鍵獲取到jscontext)
_context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//第二種情況,js是通過物件呼叫的,我們假設js裡面有一個物件 testobject 在呼叫方法
//首先建立我們新建類的物件,將他賦值給js的物件
TestJSObject *testJO=[TestJSObjectnew];
testJO.showPickerBlock = ^{
[self showImagePicker];
};
_context[@"testobject"]=testJO;
}
- (void)showImagePicker{
NSLog(@"開始喚起相機");
UIActionSheet *actionSheet = [[UIActionSheetalloc]
initWithTitle:@"請選擇檔案來源"
delegate:self
cancelButtonTitle:@"取消"
destructiveButtonTitle:nil
otherButtonTitles:@"拍照",@"從手機相簿選擇",nil];
[actionSheet showInView:self.view];
}
@end
4.上一些執行圖吧
4.1:web view的介面圖;;
4.2,點選第一個按鈕,通過調
ZTHShowPicker方法,內部block的呼叫,喚起控制器中actionsheet。
4.3,點選最後兩個按鈕,,第一個傳遞訂單號,第二個傳遞訂單號和姓名,點了兩次,列印了兩次
5.關於帶多個引數的JS回撥,OC中對應方法的寫法:
比如JS中定義了這個方法
testobject.ZTHTestParameteroneAndParametertwo("1123425255","ZTH");那ZTHTestParameteroneAndParametertwo為方法名
那麼OC中方法名可以這麼寫:1和2都是可行的
1.- (void)ZTHTestParameterone:(NSString *)orderNumber AndParametertwo:(NSString *)name;
2.- (void)ZTHTestParameteroneAnd:(NSString *)orderNumber Parametertwo:(NSString *)name;
注意:如果上面不行,也可以這麼命名
3.- (void)ZTHTestParameteroneAndParametertwo:(NSString *)orderNumber :(NSString *)name; // 第二個引數只有:沒錯
聰明的你看出來了,只要是OC的方法名去掉:(冒號)拼接起來後,,和JS的方法名一致,那麼都是會呼叫改方法的
千萬不能作死:說,我這麼拼也是我上面說的原理,那麼很遺憾的告訴你,不可以,你把And拆開了,是一個單詞,不識別(個人見解)
3.- (void)ZTHTestParameteroneA:(NSString *)orderNumberndParametertwo:(NSString *)name;
最後說兩句:這可能是JS互動中最好用的方法了,總結一下也就是我們在OC中定義一個遵守
JSExport協議的類,又定義了一個協議,宣告實現的方法和js中按鈕的點選事件方法名稱一致,用來一一對映。。最後在控制器中webview載入完畢之後,
TestJSObject *testJO=[TestJSObjectnew];
testJO.showPickerBlock = ^{
[selfshowImagePicker];
};
_context[@"testobject"]=testJO;
當然OC內部肯定封裝了很多東西匹配他們,,這不用我們管,,最後我們看看JS檔案中的一個方法名
testobject.ZTHpay();
原來是根據testobject這個物件聯絡起來的,
樓主語言能力不行,不知道有沒有繞暈你,但是你只要把demo跑一跑,問題就都能解決了。。當然你要是知道點h5的東西,那肯定更簡單咯
就先寫到這,回頭再完善,樓主其他文章裡有聯絡方式,比如這兩篇文章就有聯絡方式,如有不對的地方,歡迎指正。。想要demo的童鞋,可以加扣扣。。在下面的文章最後有。先好好上會班。
當然樓主也不是憑空就會的,本文參考連結,當時他說的是技術點,我把細節說的很細,結合下更好哦。
http://blog.csdn.net/lwjok2007/article/details/47058795
如果你喜歡這篇文章,或者有任何疑問,可以掃描第一個二維碼,加樓主好友哦
也可以掃第二個二維碼,進qq群。這裡有很多生活,職業,技術相關的文章哦。歡迎您的到來。
微訊號: 群:
相關推薦
iOS js oc相互呼叫(JavaScriptCore)
從iOS7開始 蘋果公佈了JavaScriptCore.framework 它使得JS與OC的互動更加方便了。 下面我們就簡單瞭解一下這個框架 首先我匯入framework 方法如下 點選Linked Frameworks and Libraries 的
iOS webView的高階用法之JS互動,js與oc的相互呼叫(JavaScriptCore)
重要的事情放前面 github地址:https://github.com/horisea/JSCallOCTest 歡迎star 前言:說起JS互動,很多童鞋會黯然色變,感覺很高深的樣子。大部分小夥伴只知道一種,哪一種我也說說吧。 1.在webView中將要
iOS下JS與OC互相呼叫(三)--MessageHandler
使用WKWebView的時候,如果想要實現JS呼叫OC方法,除了攔截URL之外,還有一種簡單的方式。那就是利用WKWebView的新特性MessageHandler來實現JS呼叫原生方法。 MessageHandler 是什麼? WKWebView 初始
iOS下JS與OC互相呼叫(八)--Cordova詳解+實戰
扯兩句,可以跳過 由於專案中Cordova相關功能一直是同事在負責,所以也沒有仔細的去探究Cordova到底是怎麼使用的,又是如何實現JS 與 OC 的互動。所以我基本上是從零開始研究和學習Cordova的使用,從上篇在官網實現命令列建立工程,到工程執行起來,
iOS下JS與OC互相呼叫(四)--JavaScriptCore
前面講完攔截URL的方式實現JS與OC互相呼叫,終於到JavaScriptCore了。它是從iOS7開始加入的,用 Objective-C 把 WebKit 的 JavaScript 引擎封裝了一下,提供了簡單快捷的方式與JavaScript互動。 關於JavaScriptCore的使用有兩篇很好的文章:N
iOS下JS與OC互相呼叫(六)-->WKWebView + WebViewJavascriptBridge
上一篇文章介紹了UIWebView 如何通過WebViewJavascriptBridge 來實現JS 與OC 的互相呼叫,這一篇來介紹一下WKWebView 又是如何通過WebViewJavascriptBridge 來實現JS 與OC 的互相呼叫的。WKWebView
iOS下JS與OC互相呼叫(七)--Cordova 基礎
Cordova 簡介 在介紹Cordova之前,必須先提一下PhoneGap。PhoneGap 是Nitobi軟體公司2008年推出的一個框架,旨在彌補web 和iOS 之間的不足,使得web 和 iPhone SDK 之間的互動更容易。後來又加入了Android SDK 和BlackBerry SDK,再
java 核心編程——IO流之字符流和字節流相互轉換(四)
red amr nbsp main 字符輸入 txt not stat args 1.為什麽字符流和字節流需要轉換? 這是因為有一些時候系統給你提供的只有字節流,比如說System.in標準輸入流。就是字節流。你想從他那裏得到用戶在鍵盤上的輸入,只能是以轉換流將它轉換為
JS使用WebSocket實現與Java圖形介面(swing)進行通訊
背景:做專案的時候有過這樣的一個需求,在訪問某個網頁的時候進行登入,需要瀏覽器獲取電腦的硬體資源,但是通過瀏覽器直接讀取的方式有些不便,所以想到使用Java開發一個圖形應用介面的程式讀取電腦程式通過socket通訊傳輸給html頁面用於驗證。 寫在前面:在Java伺服器這端
SpringMVC之Web引入靜態資源與規範請求字尾(三)
1.Spring3+以上的版本可以直接在springmvc-servlet.xml裡面直接設定: <mvc:annotation-driven /> <mvc
IOS中如何在多層介面之間顯示與隱藏標籤欄(UITabBar)
在做專案的時候,遇到了一個難題,使用hidesBottomWhenPushed=YES屬性設定,可以讓本級介面及其以後介面都隱藏,但是根據專案 需求,在第4層是需要顯示標籤欄的。 於是想了很多的辦法,每個要顯示的push的介面前都加了hidesBottomWhenPushe
【黑馬程式設計師】Objective-C語言學習筆記之物件的建立、使用和方法呼叫(三)
--------------------------------------------IOS期待與您交流!-------------------------------------------- 一、物件的建立 物件是由類建立,我們使用上一文章用到的類來建立物件。 說明:
iOS webView的高階用法之JS互動
前言:說起JS互動,很多童鞋會黯然色變,感覺很高深的樣子。大部分小夥伴只知道一種,哪一種我也說說吧。 1.在webView中將要請求的時候,攔截URL,進行重定向,然而該場景實用有限,網上資料也很多下面說說另一種互動方式。 - (BOOL)webView:(UIWe
iOS與網頁JS互動,看我就夠了
隨著移動APP的快速迭代開發趨勢,越來越多的APP中嵌入了html網頁,但在一些大中型APP中,尤其是電商類APP,html頁面已經不僅僅滿足展示功能,這時html要求能與原生語言進行互動、相互傳值。比如攜程APP中一個熱門景點的網頁中,點選某個景點,
iOS與JS互動,OC呼叫JS方法,JS呼叫OC方法,URL解碼
首先 iOS7開始 蘋果公佈了JavaScriptCore.framework 它使得JS與OC的互動更加方便了。 第一步:匯入framework OC 呼叫JS方法 :(一句話即可) -(void)webViewDidFinishLoad:(UIWebV
ios 中pickerView用法之國旗選擇
spa copy interface option sin source 出現 color import QRViewController控制器 // // QRViewController.m // #import "QRViewController.h" #imp
qt與js互動,並在百度地圖上繪製軌跡
前言: 獲得了照片的GPS資訊後,我們現在要做的就是把GPS資訊傳入JS中,然後通過百度地圖API將軌跡繪製出來。 一:在程式頁面載入地圖 qt5.6及之後取消了QWebkits,轉為使用QWebEngine. 在qt5.6的額ui設計師介面中,並不能直
Python高階用法之yield關鍵字
很多blog裡面說,yield關鍵字和return關鍵字非常類似。只不過yield關鍵字更復雜一點。 我們都知道,return就是返回一個值,一般位於函式的末尾(或者說,作為函式結束的標誌)。只要函式執行到return,那麼這個函式的這次呼叫就結束了。 yield並不是這
Android與js互動,帶進度條的載入H5頁面
private void initWebView() { WebSettings settings = wvResumeDetail.getSettings(); //支援JavaScript指令碼語言 settings
Fiddler高階用法之url對映請求
問題場景: 已釋出線上APP出現介面錯誤,如何測試線上APP訪問本地請求? 已釋出線上H5頁面,靜態資源或js除錯,如何對映本地js? 一般解決方案: 猜測(一般明顯問題)、 找到原發布包,修改請求資源url重新打包測試。需要前後端協調配合,耗時費力。 fiddler對映響應: