從【簡書】iOS客戶端痢站,來談?wù)凥ybrid方案細節(jié)設(shè)計

作為一位 iOS 開發(fā)人員允蜈,你應(yīng)該已經(jīng)敏感地發(fā)現(xiàn)冤吨,自己的工作涉及內(nèi)容已經(jīng)不止于 Native 的部分,因為 Hybrid App 和 ReactNative 等技術(shù)方案已經(jīng)不僅僅是概念饶套,越來越多的公司開始著手自己的 Hybrid 方案以及 ReactNative 本地化工作漩蟆。

一、引言

介紹相關(guān)概念的優(yōu)秀文章已經(jīng)有許多妓蛮,方案的實現(xiàn)原理你也應(yīng)該已經(jīng)或多或少有了一些理解怠李。不了解也沒有關(guān)系,在這篇文章里,我將用簡書 iOS 客戶端的有關(guān)特性捺癞,來探索一下 Hybrid 方案的技術(shù)細節(jié)夷蚊。文章的目的是拋磚引玉,用一個具體的項目髓介,大家很熟悉的簡書客戶端惕鼓,來幫助大家認(rèn)識 Hybrid 方案,然后親自實現(xiàn)它 唐础。

從現(xiàn)在開始箱歧,不再著眼于某一個 feature ,你需要站在一個客戶端架構(gòu)師的角度來看待問題一膨。

二呀邢、我們用到的簡書客戶端特性

1.界面構(gòu)成分析
  • 本文的主角是簡書 iOS 客戶端的文章展示頁面,這是我的一篇文章的展示頁面:
    文章展示頁面
  • 如你所見豹绪,文章內(nèi)容的展示是使用webview控件驼鹅,具體是UIWebview還是WKWebview按下不表,這不是本文的關(guān)鍵森篷。在我的demo中输钩,我使用了UIWebview
  • 在簡書發(fā)現(xiàn)tab欄的內(nèi)容頂部仲智,還有一個熱門內(nèi)容推薦的輪播圖买乃。與它類似是一些app內(nèi)的活動推介輪播圖,以及廣告頁面钓辆,它們的詳情頁內(nèi)容展示多使用webview剪验。在簡書中,這個輪播圖對應(yīng)的下一級頁面也是文章展示頁面前联,特性基本一致功戚。
    熱門內(nèi)容推薦輪播圖
  • 在 webview 的基礎(chǔ)上,添加了符合瀏覽器用戶習(xí)慣的導(dǎo)航欄按鈕似嗤。包括左側(cè)的返回關(guān)閉按鈕啸臀。以及右側(cè)的功能列表按鈕。
  • 頁面底部烁落,是一個工具欄乘粒,提供了四個常用的操作。注意這里的評論按鈕伤塌,它是我們下文的一個談?wù)擖c灯萍。
2.界面特性分析
  • 一般各家客戶端的內(nèi)容頁,都會有一些適于自己功能點的設(shè)計每聪。簡書也不例外旦棉。比如齿风,在文章內(nèi)容區(qū)域點擊作者的頭像(它本身也是網(wǎng)頁的一部分,暫且理解為對應(yīng)一個鏈接)绑洛,跳轉(zhuǎn)到了作者的個人主頁聂宾,注意,容易發(fā)現(xiàn)它是一個客戶端的原生頁面诊笤,也就是一個VC系谐。


    作者個人主頁
  • 點擊底部工具欄中的評論按鈕(原生組件),頁面(web頁面)會滑動到評論區(qū)域讨跟,如圖
    點擊評論按鈕纪他,頁面滑動
  • 對一篇文章寫下自己的評論(使用了原生組件),評論列表(網(wǎng)頁內(nèi)容)進行更新晾匠。
  • 簡書對于展示內(nèi)容作了內(nèi)外站的區(qū)分茶袒。據(jù)我自己的簡要測試,來自簡書域名www.reibang.com下的內(nèi)容凉馆,在加載過程中薪寓,是沒有進度條的,用戶體驗非常接近原生頁面澜共。而第三方的內(nèi)容向叉,則在加載過程中會出現(xiàn)一般瀏覽器中常見的加載進度條,如圖:
    第三方內(nèi)容的加載進度條
  • 對于簡書域名下的內(nèi)容嗦董,不會出現(xiàn)叉號的關(guān)閉按鈕母谎,這也是為了營造接近原生頁面的用戶體驗,讓用戶不會察覺到這是一個 web 界面京革。而第三方內(nèi)容奇唤,則會出現(xiàn)符合瀏覽器使用習(xí)慣的關(guān)閉按鈕,如上圖匹摇。

三咬扇、我們需要的儲備知識

1.Hybrid相關(guān)
  • 在Hybrid架構(gòu)中,原生界面和web頁面需要頻繁地溝通廊勃,并且是雙向的溝通懈贺。原生代碼可以構(gòu)建JavaScript語句,交由webview進行執(zhí)行供搀,從而在web頁面上實現(xiàn)需要的效果隅居。而在web頁面的js文件中钠至,也可以調(diào)用原生的Objective-C方法葛虐,從而執(zhí)行一些原生方法才能完成的操作。與此相關(guān)的庫有WebViewJavascriptBridge以及JavaScriptCore棉钧,有需要的同學(xué)可以自行了解屿脐。
2.UIWebview的相關(guān)特性
  • UIWebviewDelegate
    webview的代理方法大家想必非常熟悉,我們可以在頁面加載前、開始加載時的诵、加載完成時以及失敗時進行需要的操作万栅。這里我們需要用到的是這一條代理方法:
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
    webview根據(jù)它的返回結(jié)果來決定是否進行加載。
  • 執(zhí)行JS語句的方法:
    - (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
    我們可以自行構(gòu)建一條JS語句西疤,通過這個方法交由webview執(zhí)行
  • goback相關(guān)
    UIWebview擁有布爾類型的canGoBack烦粒、loading等屬性,通過監(jiān)測它們的值我們可以知道當(dāng)前頁面是否可以進行回退代赁,以及頁面是否正在加載扰她。
    與之對應(yīng),擁有- (void)goBack;等方法芭碍,調(diào)用之頁面會進行返回徒役,就像我們在瀏覽器中常見的那樣。

四窖壕、相關(guān)特性的模仿實現(xiàn)

對于上文中提到的相關(guān)特性忧勿,我寫了一個demo,對它們進行了簡要的模仿實現(xiàn)瞻讽。當(dāng)然簡書官方的實現(xiàn)會考慮到方方面面鸳吸,而我的demo僅是從Hybrid架構(gòu)的思想出發(fā),盼能夠拋磚引玉速勇。
這是demo中對該頁面的模仿實現(xiàn):

demo頁面

1.頁面初始化

在demo中层释,使用一條web頁面的URL來初始化VC:- (instancetype)initWithURL:(NSURL *)URL;這條URL對應(yīng)文章的鏈接。
頂部導(dǎo)航欄和底部工具欄都是系統(tǒng)原生的UINavigationBarUIToolBar快集,按鈕素材使用阿里巴巴的iconfont字體贡羔。

2.點擊作者頭像進入個人主頁

關(guān)于這個特性的實現(xiàn),如果按照 Hybrid 架構(gòu)的思想个初,屬于 Web 頁面調(diào)用原生方法乖寒,進入一個原生的VC。點擊頭像院溺,JS腳本執(zhí)行相關(guān)代碼楣嘁,調(diào)用原生方法暴露出來的接口,執(zhí)行原生方法珍逸。
我在這里用一種簡要的方法實現(xiàn):原生代碼利用之前提到的代理方法逐虚,在用戶點擊頭像后,攔截該URL谆膳,分析URL為頭像部分叭爱,直接執(zhí)行原生方法跳轉(zhuǎn)到個人主頁VC。
通過分析簡書文章頁面的網(wǎng)頁源代碼漱病,我發(fā)現(xiàn)用戶頭像對應(yīng)的URL中的Query部分买雾,有一個參數(shù)為utm_medium=note-author-link把曼。據(jù)此,在- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType代理方法中加以判斷漓穿,若是頭像鏈接嗤军,則跳轉(zhuǎn)到個人主頁VC。下面是相關(guān)代碼:

NSURL *destinationURL = request.URL;
    NSString *URLQuery = destinationURL.query;
//    簡書點擊文章中頭像時跳轉(zhuǎn)至原生頁面晃危。此處利用頭像鏈接中的一個參數(shù)作判斷
    if ([URLQuery containsString:@"utm_medium=note-author-link"])
    {
        NSLog(@"我跳轉(zhuǎn)到個人主頁啦");
        AvatorViewController *avatorVC = [[AvatorViewController alloc] init];
        [self.navigationController pushViewController:avatorVC animated:YES];
        return NO;
    }

最后返回NO是因為若是頭像鏈接叙赚,該web頁面是不需要做跳轉(zhuǎn)操作的。

這里順便講一個小tips:如果想要在Mac端查看移動端的網(wǎng)頁源代碼僚饭,那么你只需要在Safari中輸入該頁面纠俭,并且在開發(fā)選項下的用戶代理中,選擇iOS系統(tǒng)下的Safari作為代理浪慌,這時再使用源代碼查看冤荆,看到的就是移動端的網(wǎng)頁源代碼了。

3.點擊評論按鈕权纤,頁面滑動到評論區(qū)域

這個特性的實現(xiàn)方式和上面類似钓简,點擊評論按鈕,原生代碼構(gòu)建一條JS語句汹想,交由- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;方法進行執(zhí)行外邓,由web頁面執(zhí)行滑動操作。代碼如下:

- (void)scrollToCommentField
{
    [self stringByEvaluatingJavaScriptFromString:@"scrollTo(0,20500)"];
}

這里的JS語句非常簡單古掏,由于筆者的前端知識還有所欠缺损话,沒有想到可以精確滑動到評論區(qū)域的JS語句,所以簡要實現(xiàn)槽唾,點到為止丧枪。

4.原生組件寫評論,web頁面更新

這里首先需要貼一下文章頁面的網(wǎng)頁源代碼:

<!-- 評論列表 -->
  <div data-vcomp="comments-list" data-lazy="3">
    <script type="application/json">
      {"likedNote":true,"commentable":true,"publicCommentsCount":3,"noteId":2491941,"likesCount":43}
    </script>
  </div>

可以看到庞萍,頁面的評論內(nèi)容是異步加載的拧烦。所以這個功能的實現(xiàn),我
認(rèn)為比較合理的邏輯是原生組件向服務(wù)器提交一條新的評論钝计,收到成功回調(diào)之后恋博,原生組件和web頁面進行交互,執(zhí)行更新并加載評論列表的JS代碼私恬,從而看到自己發(fā)的新評論债沮。

5.內(nèi)外站頁面的區(qū)分

這里和點擊頭像的實現(xiàn)方法類似,通過攔截鏈接的URL本鸣,區(qū)分內(nèi)部鏈接和第三方鏈接疫衩,從而在開始加載的時候采用不同的加載界面,或者對于第三方鏈接單獨開啟一個第三方VC永高。
demo中關(guān)于第三方鏈接的關(guān)閉按鈕的顯示邏輯隧土,做出了相應(yīng)的處理提针。

五命爬、demo中的不足

看到這里大家應(yīng)該就會發(fā)現(xiàn)曹傀,對于提到Hybrid我們就會想到的Bridge、Router等模塊饲宛,我并沒有做明顯的限定皆愉。這樣也是為了方便大家用一種更接近以往原生代碼編寫的思維,來理解Hybrid模式艇抠。
同時幕庐,demo中較多涉及了原生代碼對web頁面做出的溝通操作。而沒有JS代碼對原生代碼的調(diào)用家淤,這是因為一來站在一個簡書客戶端的用戶和iOS開發(fā)的角度异剥,對于JS端執(zhí)行的操作,有些力不能及絮重,這本是和你共同工作的前端伙伴的任務(wù)冤寿,二來對于一篇幫助大家入門Hybrid的文章來說,從這個單方面的交互來入手青伤,管中窺豹督怜,已是足夠。

六狠角、一些感悟

其實号杠,寫了這么多,我覺得收獲到一些感悟是最重要的丰歌,下面的要講的姨蟋,可能是我覺得更為重要的思想性的東西。

1.未來的趨勢之一立帖,便是大前端團隊進行客戶端開發(fā)芬探。
  • 看到這里你發(fā)現(xiàn),如果你們的團隊想要采用Hybrid模式進行產(chǎn)品的開發(fā)厘惦,光靠iOS或者是安卓的客戶端工程師是不可能完成的偷仿。在客戶端框架的開發(fā)過程中,需要和前端的工程師溝通具體的技術(shù)細節(jié)宵蕉。比如怎樣設(shè)計接口能夠更好地兼顧客戶端和前端特點酝静,對于某個問題,如何能把握全局而不是單單從客戶端的角度來看待羡玛。這些可能是普通的iOS開發(fā)工程師和大牛的差距所在之一别智。
  • 越來越多的客戶端工程師招聘要求中,出現(xiàn)了熟悉前端語言的要求稼稿。如果你能在精通客戶端開發(fā)之余薄榛,對前端語言也游刃有余讳窟,那么在接下來的發(fā)展趨勢中,就會有更多的可能性敞恋。所以丽啡,請開始你的前端學(xué)習(xí)吧~。
2.在Hybrid模式下硬猫,如何進行產(chǎn)品技術(shù)方案的取舍
  • 如前文所見补箍,簡書客戶端對于內(nèi)部域名的內(nèi)容和第三方內(nèi)容,在展示方式上是有明顯不同的啸蜜。在閱讀簡書的文章時坑雅,讓用戶發(fā)現(xiàn)不了自己是在一個瀏覽器上進行閱讀,這在方方面面就極大改善了用戶體驗衬横。為了做到這一點裹粤,我推測簡書首先需要對自己的內(nèi)容進行非常良好的CDN加速,以保證內(nèi)容加載時不會耗時過長蜂林,同時采取一些預(yù)加載策略遥诉,二是在內(nèi)容加載時,采用與原生界面部分相同的loading界面悉尾,去掉進度條突那,模擬原生界面的加載過程。而對于第三方的鏈接构眯,采用進度條+返回愕难、關(guān)閉按鈕的設(shè)計,則更符合用戶在瀏覽器中進行閱讀的習(xí)慣惫霸,也可以和自己的內(nèi)容進行直觀區(qū)分猫缭,這也改善了用戶體驗。
  • 對于某些原生和Web頁面都可以實現(xiàn)的特性如何取舍壹店,這也是需要考慮的問題猜丹。比如,點擊評論按鈕頁面滑動硅卢,這個功能使用web頁面的滑動而非原生的控制顯然更為自然也更符合用戶習(xí)慣射窒。而對于撰寫評論的功能,使用原生的鍵盤将塑、編輯器組件脉顿,當(dāng)然就比使用web頁面的鍵入更加穩(wěn)定可控了。

七点寥、文章的demo

對于文章內(nèi)容艾疟,我寫了一個demo,這是demo地址

為了便于理解蔽莱,我為代碼寫了詳盡的注釋弟疆。
如果覺得它對你有幫助,不妨在github上為我點一個star~非常感謝盗冷!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怠苔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子正塌,更是在濱河造成了極大的恐慌嘀略,老刑警劉巖恤溶,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乓诽,死亡現(xiàn)場離奇詭異,居然都是意外死亡咒程,警方通過查閱死者的電腦和手機鸠天,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帐姻,“玉大人稠集,你說我怎么就攤上這事〖⒋桑” “怎么了剥纷?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長呢铆。 經(jīng)常有香客問我晦鞋,道長,這世上最難降的妖魔是什么棺克? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任悠垛,我火速辦了婚禮,結(jié)果婚禮上娜谊,老公的妹妹穿的比我還像新娘确买。我一直安慰自己,他們只是感情好纱皆,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布湾趾。 她就那樣靜靜地躺著,像睡著了一般派草。 火紅的嫁衣襯著肌膚如雪搀缠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天澳眷,我揣著相機與錄音胡嘿,去河邊找鬼。 笑死钳踊,一個胖子當(dāng)著我的面吹牛衷敌,可吹牛的內(nèi)容都是我干的勿侯。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼缴罗,長吁一口氣:“原來是場噩夢啊……” “哼助琐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起面氓,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤兵钮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后舌界,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掘譬,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年呻拌,在試婚紗的時候發(fā)現(xiàn)自己被綠了戒洼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狂秦。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出污它,到底是詐尸還是另有隱情绎速,我是刑警寧澤虾啦,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布锰扶,位于F島的核電站,受9級特大地震影響初家,放射性物質(zhì)發(fā)生泄漏偎窘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一笤成、第九天 我趴在偏房一處隱蔽的房頂上張望评架。 院中可真熱鬧,春花似錦炕泳、人聲如沸纵诞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浙芙。三九已至,卻和暖如春籽腕,著一層夾襖步出監(jiān)牢的瞬間嗡呼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工皇耗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留南窗,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像万伤,于是被迫代替她去往敵國和親窒悔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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