iOS 中JS和OC互調(diào)----UIWebView(基礎)

http://blog.csdn.net/y550918116j/article/details/49619847

UIWebView(基礎)

當你在項目中想嵌入網(wǎng)頁時森书,可以使用UIWebView類嵌入Web內(nèi)容。你只需要創(chuàng)建一個UIWebView對象谎势,并將它附加到一個view窗口凛膏。你還可以使用這個類來執(zhí)行頁面歷史的前進或后退。

本文主要介紹關(guān)于UIWebView的基礎脏榆,包括:加載網(wǎng)頁猖毫、實現(xiàn)代理以及JS和OC的互相調(diào)用。

1 準備工作

1.1 Html頁面

我已經(jīng)為大家創(chuàng)建了html頁面的源代碼须喂,只需要復制到記事本吁断,并將文件名改為index.html趁蕊。


這個頁面有輸入框、按鈕和做顯示用的仔役,其簡單功能是在輸入框輸入數(shù)據(jù)掷伙,點擊按鈕后顯示到顯示區(qū)域。

在瀏覽器運行可以看到如下效果又兵。

1.2 搭建項目

這個地方就不詳細描述了任柜,創(chuàng)建一個簡單項目->拉一個UIWebView到界面->UIWebView指向UIViewController的屬性名。

搭建后的核心部分如下沛厨,這里我使用的VC名為BaseVC宙地。

#import"BaseVC.h"@interfaceBaseVC() @property(weak,nonatomic)IBOutletUIWebView*webView;///< UIWebView

@end@implementationBaseVC

- (void)viewDidLoad {

[superviewDidLoad];

}@end

2 顯示W(wǎng)eb頁面

將我們創(chuàng)建好的index.html拉到項目中,至于位置就隨你高興了俄烁。

然后我們改造BaseVC的viewDidLoad方法。

- (void)viewDidLoad {

[superviewDidLoad];

// 找到index.html的路徑

NSURL*url = [[NSBundlemainBundle] URLForResource:@"index"withExtension:@"html"];

NSURLRequest*urlRequest = [NSURLRequestrequestWithURL:url];// url的位置[self.webViewloadRequest:urlRequest];// 加載頁面

}

由于我們的html頁面在項目里面级野,我們可以直接使用[NSBundle mainBundle]去尋找页屠。如果你使用的是網(wǎng)咯連接“www.baidu.com”,你可以這樣獲得NSURL。

url =[NSURL URLWithString:@"www.baidu.com"];

然后運行項目蓖柔,就可以看到和瀏覽器一樣的效果辰企。

3 代理UIWebViewDelegate

UIWebView也有代理,如果你不懂什么是代理模式况鸣,查閱我的博文《23設計模式之代理模式(Proxy)》牢贸。我們在UIWebViewDelegate發(fā)現(xiàn)了四個方法。

__TVOS_PROHIBITED@protocolUIWebViewDelegate

@optional

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType;

- (void)webViewDidStartLoad:(UIWebView*)webView;

- (void)webViewDidFinishLoad:(UIWebView*)webView;

- (void)webView:(UIWebView*)webView didFailLoadWithError:(nullableNSError*)error;

@end

這四個代理的作用分別是:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;:

將要加載一個web頁面镐捧,返回yes代表繼續(xù)加載潜索,no代表不加載。

- (void)webViewDidStartLoad:(UIWebView *)webView;:

開始加載web頁面懂酱;

- (void)webViewDidFinishLoad:(UIWebView *)webView;:

加載web頁面結(jié)束;

- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error;:

加載web頁面出錯竹习,你可以在error看到錯誤信息。

現(xiàn)在我們改造BaseVC列牺。下面都只顯示核心代碼整陌,不重要的代碼不顯示。

@interfaceBaseVC()<UIWebViewDelegate>

@property(weak,nonatomic)IBOutletUIWebView*webView;///< UIWebView

@end

@implementationBaseVC

- (void)viewDidLoad {

? ? ? ? ?[superviewDidLoad];

? ? ? ? // 找到index.html的路徑

? ? ?NSURL*url = [[NSBundlemainBundle] URLForResource:@"index"withExtension:@"html"];

NSURLRequest*urlRequest = [NSURLRequestrequestWithURL:url];// url的位置self.webView.delegate=self;// 代理UIWebViewDelegate

[self.webViewloadRequest:urlRequest];// 加載頁面

}

#pragma mark - UIWebViewDelegate#pragma mark 開始加載網(wǎng)頁

- (void)webViewDidStartLoad:(UIWebView*)webView {

? ? ? ?NSLog(@"%@", NSStringFromSelector(_cmd));

}

#pragma mark 網(wǎng)頁加載完成

- (void)webViewDidFinishLoad:(UIWebView*)webView {

? ? ? NSLog(@"%@", NSStringFromSelector(_cmd));

}

#pragma mark 網(wǎng)頁加載出錯

- (void)webView:(UIWebView*)webView didFailLoadWithError:(nullableNSError*)error {

? ? ? ? NSLog(@"%@:%@", NSStringFromSelector(_cmd), error.localizedDescription);

}

#pragma mark 網(wǎng)頁監(jiān)聽

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {

? ? ? ? NSLog(@"%@", NSStringFromSelector(_cmd));returnYES;

}

@end

運行后你會看到如下的輸出,也體現(xiàn)了三種回調(diào)的順序瞎领。如果你看到了其他輸出信息泌辫,我想你可能出錯了,請查閱前面的介紹九默,修改后再運行震放。

webView:shouldStartLoadWithRequest:navigationType:

webViewDidStartLoad:

webViewDidFinishLoad:

4 JS和OC互動

js和oc互動是一件很麻煩的事,畢竟是兩種不同的開發(fā)語言驼修。oc調(diào)js很簡單澜搅,js回調(diào)oc就比較麻煩了伍俘。

oc調(diào)js:uiwebview就自帶這樣的方法

- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

js掉oc:我們都知道js可以控制頁面的跳轉(zhuǎn),我們還可以在鏈接中攜帶參數(shù)勉躺。而UIWebView又支持攔截這些請求的操作癌瘾,這就讓我們完美的實現(xiàn)了js調(diào)oc的操作。至于更高級的方法饵溅,我們在以后給大家介紹妨退。

改變原有頁面的功能,我們要實現(xiàn)下列需求蜕企。

在輸入框輸入相關(guān)信息咬荷,點擊按鈕,將輸入的信息傳輸?shù)給c中轻掩;

oc接受到信息后幸乒,通過oc調(diào)用js的功能將信息發(fā)到js;

js收到信息后唇牧,在頁面顯示相關(guān)信息罕扎。

由于js調(diào)用oc是通過url請求發(fā)送消息,所以丐重,我們需要制定規(guī)范腔召。只有符合我們規(guī)范的請求才會執(zhí)行oc方法,否則不執(zhí)行扮惦。

這里我使用的規(guī)范是ios::oc方法名::攜帶的參數(shù)臀蛛。這樣我們在oc端,當發(fā)現(xiàn)這樣的請求時就開始攔截執(zhí)行我們的操作崖蜜。

我這里的三個參數(shù)浊仆,相信大家都能看懂,我是使用“::”分割豫领,你也可以使用其他方式分割氧卧,或者組合你喜歡的規(guī)范。

接下來就是改造oc和js了氏堤。在BaseVC添加oc接受js調(diào)用的方法體沙绝,和改寫- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType


#pragma mark - js調(diào)OC

- (void)jsCallOC:(NSString*)params {

? ? ? ? ? ? ? ?NSLog(@"%@:%@", NSStringFromSelector(_cmd), params);NSString*jsStr = [NSStringstringWithFormat:@"ocCallJS('%@')", params];

// oc調(diào)js

[self.webViewstringByEvaluatingJavaScriptFromString:jsStr];

}

#pragma mark 網(wǎng)頁監(jiān)聽

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {

? ? ? ? ? NSLog(@"%@", NSStringFromSelector(_cmd));

? ? ? // 過濾

? ? ?NSString*requestString = request.URL.absoluteString.stringByRemovingPercentEncoding;

? ? ?// 分割

? ? ? NSArray*urlComps = [requestString componentsSeparatedByString:@"::"];

if ( [urlComps count] ==3&& [@"ios"isEqualToString:[urlComps objectAtIndex:0]] ) {

? ? ? ? ? ? ? ?//解析約定的指令

? ? ? ? ? ? ? ?// 方法名

? ? ? ? ? ? ? NSString*methods = [NSStringstringWithFormat:@"%@:", [urlComps objectAtIndex:1]];

? ? ? ? ? ? ? ?SEL selector = NSSelectorFromString(methods);

? ? ? ? ? ? ? ?// 判斷類是否有方法

? ? ? ? ? ? ? ?if ( [BaseVC instancesRespondToSelector:selector]) {

? ? ? ? ? ? ? ? ? ? ? ? ? // 攜帶的參數(shù)

? ? ? ? ? ? ? ? ? ? ? NSString*params = [urlComps objectAtIndex:2];

? ? ? ? ? ? ? ? ? ? ? NSLog(@"JS調(diào)用OC代碼->UIWebView\n方法名:%@,參數(shù):%@", methods, params);

? ? ? ? ? ? ? ? ? ? ? ? ? ?// 執(zhí)行方法,攜帶參數(shù)

? ? ? ? ? ? ? ? ? ? ? ? ?[selfperformSelector:selector withObject:params];

? ? ? ? ? ? ? ? ?}else{

? ? ? ? ? ? ? ? ? ? ? ? ? ?NSLog(@"沒有提供調(diào)用的%@方法名",methods);

? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ? ?returnNO;

? ? ? ? ? }

? ? ? ? ?returnYES;

}

[self performSelector:selector withObject:params];這段代碼的意思是執(zhí)行當前頁面的方法體鼠锈,并攜帶參數(shù)闪檬。我們使用通配的方式調(diào)用方法體,使代碼更優(yōu)雅便捷购笆。

然后改變js代碼粗悯。


運行項目,然后神奇的事情發(fā)生了同欠,原來在app中嵌入網(wǎng)頁這么簡單样傍。

其他

參考資料

UIWebView Class Reference

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末横缔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子衫哥,更是在濱河造成了極大的恐慌茎刚,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撤逢,死亡現(xiàn)場離奇詭異膛锭,居然都是意外死亡,警方通過查閱死者的電腦和手機蚊荣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門初狰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人互例,你說我怎么就攤上這事奢入。” “怎么了媳叨?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵腥光,是天一觀的道長。 經(jīng)常有香客問我肩杈,道長柴我,這世上最難降的妖魔是什么解寝? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任扩然,我火速辦了婚禮,結(jié)果婚禮上聋伦,老公的妹妹穿的比我還像新娘夫偶。我一直安慰自己,他們只是感情好觉增,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布兵拢。 她就那樣靜靜地躺著,像睡著了一般逾礁。 火紅的嫁衣襯著肌膚如雪说铃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天嘹履,我揣著相機與錄音腻扇,去河邊找鬼。 笑死砾嫉,一個胖子當著我的面吹牛幼苛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播焕刮,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼舶沿,長吁一口氣:“原來是場噩夢啊……” “哼墙杯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起括荡,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤高镐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后一汽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體避消,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年召夹,在試婚紗的時候發(fā)現(xiàn)自己被綠了过吻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡礼旅,死狀恐怖贸人,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鲸阔,我是刑警寧澤偷霉,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站褐筛,受9級特大地震影響类少,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渔扎,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一硫狞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晃痴,春花似錦残吩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至紧唱,卻和暖如春活尊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背漏益。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工蛹锰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遭庶。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓宁仔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親峦睡。 傳聞我的和親對象是個殘疾皇子翎苫,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • http://www.cnblogs.com/mddblog/p/5281748.html 一权埠、整體介紹 UIWe...
    F麥子閱讀 1,232評論 0 2
  • 一呐粘、簡介 近兩年隨著HTML5的迅速發(fā)展與日趨成熟满俗,越來越多的移動開發(fā)者選擇使用HTML5來進行混合開發(fā),不僅節(jié)約...
    RainyGY閱讀 1,870評論 1 12
  • 前言 關(guān)于UIWebView的介紹作岖,相信看過上文的小伙伴們唆垃,已經(jīng)大概清楚了吧,如果有問題痘儡,歡迎提問辕万。 本文是本系列...
    CoderLF閱讀 8,963評論 2 12
  • 一、簡介 近兩年隨著HTML5的迅速發(fā)展與日趨成熟沉删,越來越多的移動開發(fā)者選擇使用HTML5來進行混合開發(fā)渐尿,不...
    寶寶teacher閱讀 2,305評論 3 15
  • IOS之UIWebView的使用 剛接觸IOS開發(fā)1年多,現(xiàn)在對于 混合式 移動端開發(fā)越來越流行矾瑰,因為開發(fā)成本上砖茸、...
    學無止境666閱讀 45,786評論 5 53