色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > iOS hybrid App 的實現(xiàn)原理及性能監(jiān)測

          iOS hybrid App 的實現(xiàn)原理及性能監(jiān)測

          作者: 時間:2018-08-08 來源:網(wǎng)絡 收藏

          本文引用地址:http://cafeforensic.com/article/201808/385949.htm

          作者董一凡自述:作為一名寫了十年代碼的程序員,目前我最擅長的領域是移動平臺的客戶端開發(fā),在移動領域的開發(fā)時間超過七年,前前后后涉獵過很多個平臺。隨著大部分移動平臺自己走向死亡,現(xiàn)在我也主要專注在了和Android兩大移動平臺,偶爾也會客串下Windows這個不知道是移動還是桌面的平臺。 十年前,我剛入行的時候,曾經(jīng)認為自己將會永遠做一個C++程序員,于是花了大量時間在C++上。現(xiàn)在C++也是我工作所用的主力語言之一,工作之外也會偶爾寫點什么娛樂一下。 寫了一些年程序后,終于意識到了之前定位的狹隘,于是開始廣泛的學習各種技術,各種各樣的語言也學了很多,值得慶幸的是,幾年折騰下來,我一直也沒有對寫代碼這件事感到厭倦,于是我又認為自己將會永遠把開發(fā)做下去。 現(xiàn)在,我也覺得開發(fā)是一個可以終身做下去的事業(yè),不過除了事業(yè)我還想追求更多的東西,從這些年的經(jīng)歷來看,其中貫穿始終的就是在不停的學習,想明白這一點后,我開始除技術之外更廣領域的學習,比如日語,畫畫,設計,鋼琴等等,給自己的定位也變成了在今后作為一名終身學習者。

          hybrid App 簡單介紹

          大家應該多少都知道, 設備上有兩種入口,一是通過 App Strore 下載一個個的 App,另一個是用系統(tǒng)瀏覽器去訪問網(wǎng)頁。前者我們一般稱為原生應用,后者就是傳統(tǒng)意義上的網(wǎng)頁。兩者各有特點,開發(fā)一個原生應用,一般是使用 Apple 給我們提供的開發(fā)工具和 Cocoa 框架。優(yōu)勢就是可以利用到系統(tǒng)的所有特性,做出很酷的特性而不損失任何的性能,而缺點就是每次 App 提供新功能都必須重新打包 App,提交給 Apple 進行審核,通過以后再上架 App Store,最后用戶再升級,平均需要兩周的時間。相反,寫一個網(wǎng)頁則完全沒有這個限制,服務器做一次升級,用戶通過瀏覽器再訪問,就是最新的了,而寫網(wǎng)頁的缺點則是受到很大的限制,很多系統(tǒng)特性是無法訪問的,而且性能往往不高,以至于很難實現(xiàn)一些很酷的效果。

          鑒于原生應用和網(wǎng)頁各有優(yōu)勢,所以就衍生出了一種介于兩者之間的開發(fā)方式--混合應用(hybrid App)。其特點是在原生應用中嵌入一個瀏覽器組件,然后通過某種方式,讓原生代碼和網(wǎng)頁能夠雙向通訊,結果就是可以在需要原生功能的時候使用原生功能,而適合放在網(wǎng)頁端的部分就放在服務器上。某種程度上利用到了兩者的優(yōu)勢。另一個優(yōu)勢就是,由于網(wǎng)頁技術在 iOS 和 Android 上是一樣的,所以網(wǎng)頁的這部分也就天然可以跨平臺了。

          二 如何實現(xiàn) hybrid App

          實現(xiàn)一個 hybrid App 最簡單的方法就是使用 Apache Cordova 開源框架。Cordova 已經(jīng)幫你做好了所有的網(wǎng)頁和原生應用之間的橋接工作,你需要做的就是根據(jù)他的文檔去寫對應的網(wǎng)頁代碼和原生代碼就行了。具體請參考官方網(wǎng)站

          可惜的是,我們總有些場景無法使用 Cordava,比如我曾經(jīng)的一個項目,項目主要是要提供一個 SDK ,SDK 本身要使用 hybrid 的技術。但是 SDK 的用戶可能也會用到 Cordova,有些情況下,兩者用的 Cordova 為不同版本,正好無法兼容。于是就需要自己去實現(xiàn) hybrid App 的底層了。

          三 iOS hybrid App 的底層實現(xiàn)

          1. 原生代碼調用網(wǎng)頁中的 JavaScript 函數(shù)

          假設我們的網(wǎng)頁中有如下代碼

          [scripttype=text/javascript]functionmyFunc(){returnTextfromweb}[/script]

          原生代碼可以用如下方式調用 myFunc()

          NSString*result=[self.webViewstringByEvaluatingJavaScriptFromString:@myFunc()];

          在這里 result 就等于 Text from web

          2. 網(wǎng)頁中的 JavaScript 調用系統(tǒng)的原生代碼

          這一步比上邊的要復雜一些,iOS 不像 Android 可以直接給網(wǎng)頁中的 JavaScript 函數(shù)注入一個原生代碼的接口。這里我們會用一個比較曲折的方式來實現(xiàn)。

          假設 Objective-C 的類里有一個方法

          -(void)nativeFunction:(NSString*)args{}

          JavaScript 里我們用下邊的方法來最終調用到上邊這個方法

          window.JSBridge.callFunction(callNativeFunction,somedata);

          在我們的頁面里,是沒有 JSBridge.callFunction 存在的,這一步我們要在原生代碼端注入。

          在 webView 的 delegate 的 - (void)webViewDidFinishLoad:(UIWebView *)webView 里我們用下邊的方式注入 JavaScript

          NSString*js=@(function(){window.JSBridge={};window.JSBridge.callFunction=function(functionName,args){varurl=bridge-js://invoke?;varcallInfo={};callInfo.functionname=functionName;if(args){callInfo.args=args;}url+=JSON.stringify(callInfo);varrootElm=document.documentElement;variFrame=document.createElement(IFRAME);iFrame.setAttribute(src,url);rootElm.appendChild(iFrame);iFrame.parentNode.removeChild(iFrame);};returntrue;})();;[webViewstringByEvaluatingJavaScriptFromString:js];

          簡單解釋一下,首先我們在 window 里創(chuàng)建一個叫 JSBridge 的對象,然后在里邊定義一個方法 callFunction,這個方法的作用是把兩個參數(shù)打包為 JSON 字符串,然后附帶到我們自定義的 URL bridge-js://invoke? 后邊,最后用 IFRAME 的方式來加載這個 URL

          這么做的原因是,當加載 IFRAME 的時候,就會調用 webView 的 delegate 的 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 方法,其中 request 就是我們剛才自定義的那個 URL,在這個方法里我們做如下處理

          NSURL*url=[requestURL];NSString*urlStr=url.absoluteString;return[selfprocessURL:urlStr];

          processURL 函數(shù)如下

          -(BOOL)processURL:(NSString*)url{NSString*urlStr=[NSStringstringWithString:url];NSString*protocolPrefix=@bridge-js://invoke?;if([[urlStrlowercaseString]hasPrefix:protocolPrefix]){urlStr=[urlStrsubstringFromIndex:protocolPrefix.length];urlStr=[urlStrstringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];NSError*jsonError;NSDictionary*callInfo=[NSJSONSerializationJSONObjectWithData:[urlStrdataUsingEncoding:NSUTF8StringEncoding]options:kNilOptionserror:jsonError];NSString*functionName=[callInfoobjectForKey:@functionname];NSString*args=[callInfoobjectForKey:@args];if([functionNameisEqualToString:@callNativeFunction]){[selfnativeFunction:args];}returnNO;}returnYES;}

          從 bridge-js://invoke? 這個自定義的 URL 里邊把附帶在后邊 JSON 字符串解析出來,然后判斷 functionname key 的值如果是 callNativeFunction 那么就去調用原生方法 nativeFunction, 如果需要實現(xiàn)更多的方法調用,只要添加這個映射關系就行了。

          至此,JavaScript 和 Objective-C 代碼的雙向調用就都實現(xiàn)了。

          四 性能監(jiān)測

          Hybrid 和原生應用之間的爭論一直以來都不少,其核心問題其實就是如何平衡開發(fā)成本和用戶體驗之間的關系。Hybrid的開發(fā)成本一般來說要低于原生應用,然后其體驗總是要差一些。為了讓 Hybrid 的用戶體驗能更可能的接近原生應用,性能監(jiān)測就顯的更為重要了。

          影響 App 使用體驗一般來講有兩個主要方面

          第一方面是 UI 的響應速度,UI 的流暢與否給用戶的體驗是非常不一樣的。對這方面的性能監(jiān)測,一般的做法就是在主要的交互函數(shù)里打上時間戳,而對于系統(tǒng)的 View,也可以采用 Method Swizzle 的方法對所有的系統(tǒng)函數(shù)的調用時間進行統(tǒng)計。

          二是網(wǎng)絡,而由于現(xiàn)在的大部分 App 都多少有了網(wǎng)絡請求,所以網(wǎng)絡的請求速度也會很大程度上影響用戶體驗。網(wǎng)絡問題在 Hybrid App 就體現(xiàn)的更明顯。Hybrid App 總是會去加載服務器端的頁面,在頁面加載出來之前,很可能整個手機屏幕是空白的,如果空白時間太長,將是一個很糟糕的事情,所以實時的監(jiān)測請求網(wǎng)頁的時間,以及頁面的加載速度就非常有必要了。針對 webView,建議在它的 delegate 的幾個方法里打上時間戳,以此來統(tǒng)計頁面請求和加載的時間。

          總之實現(xiàn)起來,并不是一個非常復雜的工作。然而性能監(jiān)測的工作,實現(xiàn)只是其中的一個方面,由于用戶的使用習慣,實際的網(wǎng)絡環(huán)境各種問題,性能監(jiān)測并不是在開發(fā)階段監(jiān)測一下就算完了的,一般來說,總是得把監(jiān)測工作部署到最終用戶的手機上去的,如果是一個用戶量不小的 App,那么如何把收集到的大量數(shù)據(jù)很好的統(tǒng)計顯示出來,這完全是另一回事了,把這事做好,要牽扯到很多的數(shù)據(jù)組織,前端展示的工作,實際的實施絕對不是個簡單的工作。

          所幸,現(xiàn)在已經(jīng)有很多公司幫我們完成了這個工作,比如 New Relic,App dynamics,Compuware,聽云等。這次我們就以聽云為例,看看他們是怎么來做性能監(jiān)測這件事的。

          五 聽云探針(iOS App版)的使用

          聽云對 App 的性能監(jiān)測使用起來還是比較簡單的,簡單步驟如下

          申請完聽云的賬戶后,在添加 App 的地方填寫相關信息

          之后就會得到一個唯一的 App Key

          然后下載聽云的 iOS SDK 的 Framework,拷貝到項目中,注意添加以下 4 個額外的系統(tǒng)庫

          • CoreTelephony.framework

          • Security.framework

          • SystemConfiguration.framework

          • libz.dylib

          然后在 App 的 pch 文件中包含聽云 App 探針的頭文件

          #import

          最后將 main.m 中加入

          [NBSAppAgentstartWithAppID:App_Key];

          代碼一般為下邊的樣子

          intmain(intargc,char*argv[]){@autoreleasepool{[NBSAppAgentstartWithAppID:App_Key];returnUIApplicationMain(argc,argv,nil,NSStringFromClass([AppDelegateclass]));}}

          這樣整個集成工作就完成了。啟動 App,如果在 Log 日志中有如下內容顯示就表示代碼集成成功

          NBSAppAgent2.2.2.1---->start!SuccesstoconnecttoNBSSERVER

          六 聽云監(jiān)測數(shù)據(jù)觀察

          1. 匯總數(shù)據(jù)

          登錄到聽云的后臺管理頁面,首先我們可以看到匯總的監(jiān)測數(shù)據(jù),圖表的效果還是不錯的,鼠標放到每個數(shù)據(jù)點上會顯示詳細的數(shù)據(jù)。

          總體看來,分為兩大類,一類是應用交互性能,這類主要是監(jiān)測 UI 響應情況,會給出 view 加載,以及 layout 的時間匯總。如果發(fā)現(xiàn)某一項參數(shù)出現(xiàn)異常,那也許就是需要重構 UI 的信號了。另一類是網(wǎng)絡性能,包含網(wǎng)絡請求的響應時間等。

          2. Web View

          重要的東西最先講,這個部分是聽云目前最有特色的部分(好像是首家這么做的,目前還沒在其他的類似服務里看到這個功能)。通常我們進行網(wǎng)絡性能監(jiān)測的時候,給出的是整個網(wǎng)絡請求的情況,這在瀏覽器里邊來說,整個網(wǎng)絡請求其實也就是頁面的請求,兩者沒有區(qū)別。而到了 App 里,同樣是 http 請求,有可能是來自 web service 的調用,也可能是來自 web view 加載頁面。而后者正好是我們講的 Hybrid App 的主要實現(xiàn)方式。聽云的這個條目就是完全只給出 web view 所進行的請求情況,換句話說,這是我們用來監(jiān)測 Hybrid App 網(wǎng)絡性能的最好數(shù)據(jù)。

          (1)HTTP請求

          這里有所有 web view 所加載的頁面的匯總數(shù)據(jù)。

          (2)頁面加載

          聽云除了給出網(wǎng)絡性能的數(shù)據(jù),這里還很貼心的給出了頁面加載的匯總數(shù)據(jù),要知道現(xiàn)在的網(wǎng)頁是有可能非常復雜,包含很多頁面元素的,在桌面端問題也許不明顯,但在移動端,太復雜的效果也許會大大的拖慢加載速度,影響用戶體驗。根據(jù)這里給出的頁面加載數(shù)據(jù),就可以有針對性的去優(yōu)化網(wǎng)頁了。

          3. 網(wǎng)絡

          這個條目主要是 App 的所有網(wǎng)絡請求的數(shù)據(jù)。

          (1)拓補圖

          這主要是一個分類匯總的數(shù)據(jù),可以分別查看是自己的 App 所以及第三方服務所發(fā)送的網(wǎng)絡請求的匯總數(shù)據(jù)。

          (2)HTTP請求

          顧名思義,這里是所有 http 請求的詳細數(shù)據(jù),分別顯示了響應最慢的主機,以及吞吐量最高的主機。

          (3)地域

          這個條目比較有意思,用顏色的方式標示出了世界各國的平均響應時間,點擊對應的國家還可以繼續(xù)進入到下一級,最后可以進入到詳細的網(wǎng)絡數(shù)據(jù)分析頁面。

          (4)組合分析

          這個頁面在中國的網(wǎng)絡環(huán)境下是非常有用的,它可以根據(jù)運營商,地域,接入方式來給出匯總數(shù)據(jù)。要知道中國的網(wǎng)絡環(huán)境非常復雜,不同運營商之間,甚至同一運營商在不同的地區(qū)網(wǎng)絡互通情況會相差非常大。有了這里的數(shù)據(jù),就可以有針對性的去部署服務器,優(yōu)化網(wǎng)絡體驗。

          4. 交互

          進入交互分析具體項

          在這里我們可以詳細的看到 ViewController 以及 View 的每一個系統(tǒng)函數(shù)的調用時間,通過這個數(shù)據(jù)就可以非常好的分析是哪個一個 ViewController 出了問題,對應的去重構就可以了。

          交互分析下邊的幾項是通過一定的條件來看 UI 交互的具體數(shù)據(jù),可以通過版本進行過濾,這樣就可以方便的過濾掉已經(jīng)把問題修改掉了的版本。還可以通過操作系統(tǒng)(iOS/Android)和設備來看各自的交互響應的數(shù)據(jù)。

          5. 其他

          除了性能分析,聽云的數(shù)據(jù)里也有常見的崩潰數(shù)據(jù),活躍數(shù)以及事件監(jiān)測等。這里就不詳細展開了

          七 總結

          Hybrid App 在某些特定場景是非常有用的,然而也確實有它的局限性,特別是對交互要求很高的地方,使用它是不太合適,畢竟它還是基于網(wǎng)頁技術。不過html5在移動端的發(fā)展也非常迅速,也許會有更好的未來也說不定??傊莆者@個技術是不會錯的。另外由于網(wǎng)頁端很可能會成為我們性能瓶頸,所以要時時注意測試相關部分的性能表現(xiàn),也建議使用一些應用性能監(jiān)測的第三方服務。這樣能夠更好的定位產(chǎn)品環(huán)境的問題。



          關鍵詞: iOS

          評論


          相關推薦

          技術專區(qū)

          關閉