IOS與網(wǎng)頁JS交互詳解及實例
IOS與網(wǎng)頁JS交互
隨著移動APP的快速迭代開發(fā)趨勢,越來越多的APP中嵌入了html網(wǎng)頁,但在一些大中型APP中,尤其是電商類APP,html頁面已經(jīng)不僅僅滿足展示功能,這時html要求能與原生語言進行交互、相互傳值。比如攜程APP中一個熱門景點的網(wǎng)頁中,點擊某個景點,可以跳轉到原生中的該景點詳情頁控制器。
為此,我整理了三種最常用最便捷有效的OC與JS交互的方式,供大家學習交流。
第一種:JS給OC傳值。
1. 技術方案:使用JavaScriptCore.framework框架
2. 使用場景: 網(wǎng)頁中代碼中的某個方法,比如點擊事件方法,將該方法的參數(shù)傳值給OC,供OC使用。
比如:攜程APP中一個熱門景點的網(wǎng)頁中,有很多個熱門景點,點擊某個景點的圖片或名稱,可以跳轉到原生中的該景點詳情頁控制器。
3. 代碼實現(xiàn)如下:
OC里要實現(xiàn)的代碼:
拖入JavaScriptCore.framework靜態(tài)庫,遵守UIWebViewDelegate代理協(xié)議。
在-webViewDidFinishLoad:方法里編寫如下代碼:
- (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);
}
};
}
其中 passValue 是JS的函數(shù)名,得到的 arg數(shù)組 里面為JS的 passValue 函數(shù)的參數(shù),即 JS要傳給OC的參數(shù)。
JS里要實現(xiàn)的代碼:
function testClick()
{
var str1=document.getElementById("text1").value;
var str2=document.getElementById("text2").value;
passValue(str1,str2);
}
在需要給OC傳值的函數(shù)里(例如:testClick())直接調用 passValue()函數(shù),將值傳進去即可。
第二種:JS給OC傳值。
1. 技術方案:使用自定義url方法,每次點擊網(wǎng)頁
2. 使用場景: 網(wǎng)頁中代碼中的某個方法,比如點擊事件方法,將該方法的參數(shù)傳值給OC,供OC使用。
比如:攜程APP中一個熱門景點的網(wǎng)頁中,有很多個熱門景點,點擊某個景點的圖片或名稱,可以跳轉到原生中的該景點詳情頁控制器。
3. 代碼實現(xiàn)如下:
JS里要實現(xiàn)的代碼:
function testClick()
{
var str1=document.getElementById("text1").value;
var str2=document.getElementById("text2").value;
// "objc://"為自定義協(xié)議頭;
// str1&str2為要傳給OC的值,以":/"作為分隔
window.location.href="objc://"+":/"+str1+":/"+str2;
}
在需要給OC傳值的函數(shù)里(例如:testClick())寫如上格式的代碼。
其中 objc:// 是自定義的協(xié)議頭,str1與str2為JS要傳給OC的值。
OC里要實現(xiàn)的代碼:
//遵守UIWebViewDelegate代理協(xié)議。
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
//拿到網(wǎng)頁的實時url
NSString *requestStr = [[request.URL absoluteString] stringByRemovingPercentEncoding];
//在url中尋找自定義協(xié)議頭"objc://"
if ([requestStr hasPrefix:@"objc://"]) {
// 以"://"為中心將url分割成兩部分,放進數(shù)組arr
NSArray *arr = [requestStr componentsSeparatedByString:@"://"];
NSLog(@"%@",arr);
//取其后半段
NSString *paramStr = arr[1];
NSLog(@"%@",paramStr);
//以":/"為標識將后半段url分割成若干部分,放進數(shù)組arr2,此時arr2[0]為空,arr2[1]為第一個傳參值,arr2[2]為第二個傳參值,以此類推
NSArray *arr2 = [paramStr componentsSeparatedByString:@":/"];
NSLog(@"%@",arr2);
//取出參數(shù),進行使用
if (arr2.count) {
NSLog(@"有參數(shù)");
[self doSomeThingWithParamA:arr2[1] andParamB:arr2[2]];
}else{
NSLog(@"無參數(shù)");
}
return NO;
}
return YES;
}
//對JS傳來的值進行調用
- (void)doSomeThingWithParamA:(id)paramA andParamB:(id)paramB{
NSLog(@"%@ %@", paramA, paramB);
}
第三種:利用第三方庫實現(xiàn)JS與OC的相互傳值。
1. 技術方案:使用WebViewJavascriptBridge三方庫
2. 使用場景: 網(wǎng)頁中代碼中的某個方法,比如點擊事件方法,將該方法的參數(shù)傳值給OC,供OC使用。
比如:攜程APP中一個熱門景點的網(wǎng)頁中,有很多個熱門景點,點擊某個景點的圖片或名稱,可以跳轉到原生中的該景點詳情頁控制器。
或者將原生中的用戶信息傳遞給網(wǎng)頁,以便其個性化展示
3. 代碼實現(xiàn)如下:
OC傳值給JS
JS里需要實現(xiàn)的代碼:
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
//調用上面定義的函數(shù)
setupWebViewJavascriptBridge(function (bridge){
//OC傳值給JS 'testJavascriptHandler'為雙方自定義好的統(tǒng)一方法名;'data'是OC傳過來的值;'responseCallback'是JS接收到之后給OC的回調
bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {
//打印OC傳過來的值
log('ObjC called testJavascriptHandler with', data)
var responseData = { 'Javascript Says':'Right back atcha!' }
log('JS responding with', responseData)
//給OC的回調
responseCallback(responseData)
})
OC里需要實現(xiàn)的代碼:
導入第三方庫WebViewJavascriptBridge;遵守UIWebViewDelegate;
//設置第三方Bridge是否可用
[WebViewJavascriptBridge enableLogging];
//關聯(lián)webView和bridge
_bridge = [WebViewJavascriptBridge bridgeForWebView:web];
[_bridge setWebViewDelegate:self];
//OC給JS傳值,雙方自定義一個統(tǒng)一的方法名'testJavascriptHandler';data里即為要傳過去的值
[_bridge callHandler:@"testJavascriptHandler" data:@{@"年齡":@"20"}];
JS傳值給OC
JS里需要實現(xiàn)的代碼:
//點擊網(wǎng)頁上一個按鈕時
callbackBt.onclick = function()
{
var str1=document.getElementById("text1").value;
var str2=document.getElementById("text2").value;
//JS給OC傳值。'passValue'為雙方自定義的統(tǒng)一方法名;'str1'&'str2'為要傳的值; response為OC收到后給JS的回調
bridge.callHandler('passValue', {str1,str2}, function(response) {
})
}
OC里需要實現(xiàn)的代碼:
導入第三方庫WebViewJavascriptBridge;遵守UIWebViewDelegate;
//設置第三方Bridge是否可用
[WebViewJavascriptBridge enableLogging];
//關聯(lián)webView和bridge
_bridge = [WebViewJavascriptBridge bridgeForWebView:web];
[_bridge setWebViewDelegate:self];
//js給oc傳值.'passValue'為雙方自定義的統(tǒng)一方法名;'data'為JS傳過來的值;'responseCallback'為OC收到值后給JS返回的回調
[_bridge registerHandler:@"passValue" handler:^(id data, WVJBResponseCallback responseCallback) {
//打印js傳過來的值
NSLog(@"%@", data);
//返回給js的值
responseCallback(@"收到了");
}];
需要注意的是:不論哪方給哪方傳值,傳值的方法名稱與對應接收值的方法名稱要保持一致。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- iOS中的NSURLCache數(shù)據(jù)緩存類用法解析
- Objective-C的緩存框架EGOCache在iOS App開發(fā)中的使用
- C++開發(fā)在IOS環(huán)境下運行的LRUCache緩存功能
- 使用Javascript判斷瀏覽器終端設備(PC、IOS(iphone)、Android)
- iOS 條碼及二維碼掃描(從相冊中讀取條形碼/二維碼)及掃碼過程中遇到的坑
- iOS實現(xiàn)時間顯示幾分鐘前,幾小時前以及剛剛的方法示例
- IOS正則表達式判斷輸入類型(整理)
- iOS 仿百度外賣-首頁重力感應的實例
- IOS 開發(fā)之應用喚起實現(xiàn)原理詳解
- IOS TextFiled與TextView 鍵盤的收起以及處理鍵盤遮擋
- IOS Cache設計詳細介紹及簡單示例
相關文章
iOS應用中發(fā)送HTTP的get請求以及HTTP異步請求的方法
這篇文章主要介紹了iOS應用中發(fā)送HTTP的get請求以及HTTP異步請求的方法,代碼為傳統(tǒng)的Objective-C語言,說明都簡單地融入于注釋之中,需要的朋友可以參考下2016-02-02
iOS應用設計模式開發(fā)中職責鏈(責任鏈)模式的實現(xiàn)解析
這篇文章主要介紹了iOS應用設計模式開發(fā)中職責鏈模式的相關實現(xiàn)解析,示例代碼為傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-03-03
iOS runtime forwardInvocation詳解及整理
這篇文章主要介紹了 iOS runtime forwardInvocation詳解及整理的相關資料,需要的朋友可以參考下2017-02-02
iOS保存App中的照片到系統(tǒng)相冊或自建相冊的方法
這篇文章主要介紹了iOS保存App中的照片到系統(tǒng)相冊或自建相冊的方法,示例代碼為傳統(tǒng)的Objective-C語言寫成,需要的朋友可以參考下2016-04-04

