iOS老司機的跨端跨平臺Hybrid開發Tips
本文正在參加「金石計劃 . 瓜分6萬現金大獎」
前言
- Native與H5的混合開發是目前大前端繞不開的技術點, 在實際業務場景中有各種各樣的應用
- 很多一線開發同學都會使用
Hybrid混合開發
中的各種技術及API, 去完成各種相互呼叫的需求 - 知其然, 知其所以然. 作為一個有追求的大前端從業者, 我們一起來探究一下iOS中的
Hybrid混合開發
的前世今生. - 文章純手打, 拋磚引玉, 如有錯誤還請評論區指正, 先行謝過了:)
1. 原生與前端互動
1.1 什麼是JavaScriptCore?
JavaScriptCore
為原生程式語言Objective-C
、Swift
提供呼叫JavaScript
程式的動態能力,還能為 JavaScript
提供原生能力來彌補前端所缺能力。- 橋樑作用
JavaScriptCore
,原本是WebKit
中用來解釋執行JavaScript
程式碼的核心引擎-
- 解釋執行
JavaScript
程式碼的引擎自JavaScript
誕生起就有,不斷演進,一直髮展到現在
- 解釋執行
-
- 如今蘋果公司有
JavaScriptCore
引擎、谷歌有 V8 引擎
- 如今蘋果公司有
-
- iOS7 之前,蘋果公司沒有開放
JavaScriptCore
引擎。
- iOS7 之前,蘋果公司沒有開放
-
- 從 iOS7 開始,蘋果公司開始將
JavaScriptCore
框架引入 iOS 系統,並將其作為系統級的框架提供給開發者使用
- 從 iOS7 開始,蘋果公司開始將
JavaScriptCore
框架的框架名是 JavaScriptCore.framework。
1.2 JavaScriptCore 框架的關鍵類分解剖析
- JavaScriptCore 框架主要由
JSVirtualMachine
、JSContext
、JSValue
類組成。 JSVirturalMachine
的作用,是為 JavaScript 程式碼的執行提供一個虛擬機器環境。-
JSContext
是 JavaScript 執行環境的上下文,負責原生和 JavaScript 的資料傳遞。
-
-
JSValue
是JavaScript
的值物件,用來記錄 JavaScript 的原始值,並提供進行原生值物件轉換的介面方法。
-
1.3 JavaScript 程式碼的 JavaScriptCore 和原生應用是怎麼互動的呢
-
JavaScriptCore
和原生應用要想互動,首先要有JSContext
。 -
除了
Block
外,我們還可以通過JSExport
協議來實現在JavaScript
中呼叫原生程式碼, -
- 也就是原生程式碼中讓遵循
JSExport
協議的類,能夠供JavaScript
使用。
- 也就是原生程式碼中讓遵循
``` - (void)testJavaScriptCore { // 建立JSVirtualMachine物件 JSVirtualMachine jsvm = [JSVirtualMachine new]; // 使用 jsvm的JSContext物件 JSContext ct = [[JSContext alloc] initWithVirtualMachine:jsvm];
//通過JavaScriptCore在原生程式碼中呼叫JavaScript變數 // 解析執行JavaScript指令碼 [ct evaluateScript:@"var i = 1 + 2"];
// 轉換"i"變數為原生物件 NSNumber *iNumber = [ct[@"i"] toNumber]; NSLog(@"var i is %@, iNumber is %@", ct[@"i"], iNumber);
// 解析執行 JavaScript指令碼 [ct evaluateScript:@"function subtraction(x, y) { return x - y }"];
// 獲得 subtraction 函式 JSValue *subtraction = ct[@"subtraction"];
// 傳入引數執行subtraction函式 JSValue *resultValue = [subtraction callWithArguments:@[@(3), @(1)]];
// 將 subtraction 函式執行的結果轉成原生NSNumber來使用
NSLog(@"function is %@, reusltValue is %@", subtraction, [resultValue toNumber]);
}
```
1.4 iOS中Native和JavaScriptCore互動小結
- 總的來說,
JavaScriptCore
提供了前端與原生相互呼叫的介面,介面層上主要用的是JSContext
和JSValue
這兩個類, - 通過
JSValue
的evaluateScript
方法、Block
賦值context
、JSExport
協議匯出來達到互通的效果。
2. Hybrid混合開發框架的幾個里程牌
2.1 基於JavaScript和WebView的跨平臺方案Cordova
Cordova
的前身是PoneGap
, 後被Apache收購, 成立Cordova
專案組Cordova
的方案主要是通過H5來構建頁面, 再將其顯示在各個平臺的WebView中.Cordova
官方圖:
2.1.1 Cordova的優缺點
Cordova
的優點顯而易見, 背靠Apache這樣的大廠, 底層程式碼穩定, 文件清晰, 應用廣泛.- 但是它預設是不能呼叫Native的一些服務的(如相機、藍芽等硬體), 所以需要通過JavaScript進行橋接呼叫Native的一些API來完成某些基於硬體的功能.
- 本身的使用者體驗、效能相對Native控制元件並不是太流暢, Native更新迭代的過程中容易產生很多適配問題.
2.2 久經考驗的React Native
React Native
是Facebook在2015年4月開源出來的跨平臺開發框架, 是Facebook基於早先開源的JS框架React在原生移動應用平臺的衍生應用.React Native
使用JS語言, 類似於H5的JSX
, 以及CSS來開發移動App, 降低了使用React框架的H5前端同學的學習成本.- 在保留基本渲染能力的基礎上, 用原生自帶的UI元件實現核心渲染引擎, 從而保證了良好的渲染效果.
- 但是, 由於React Native的本質是通過JavaScript VM呼叫原生介面, 相對Native元件通訊較低效, 而且RN框架本身不負責渲染, 是間接通過原生進行渲染的.(參考大廠Airbnb由RN轉向Native.)
2.3 Google主推的跨平臺解決方案Flutter
- Flutter使用Skia渲染引擎, 直接通過CPU、GPU進行圖形繪製, 不需要依賴任何Native控制元件.
- Android作業系統中, 我們編寫的Native控制元件實際上也是依賴於Skia進行繪製渲染, 所以Flutter在某些Android小K做系統上, 甚至還要高於安卓原生(因為安卓原生中的Skia必須隨著作業系統進行更新, 二Flutter SDK中總是保持最新的Skia引擎).
- 而類似於React Native框架, 必須通過橋接操作先轉成Native控制元件進行呼叫, 之後再進行渲染.
3. 一些小結
- 大前端中主流的3種跨平臺框架各有利弊, 選取哪個方案, 還是要由實際業務場景及專案具體情況決定.
- 就像我們討論
OOP POP FunctionalProgramming
究竟是哪個好? - 最後還是MOP(Market Oriented Programming), 市場和具體業務情況決定了我們的技術選型, 應避免一味的炫技. 畢竟, 技術的成長和業務的發展是相輔相成的雙生:)
發文不易, 喜歡點讚的人更有好運氣👍 :), 定期更新+關注不迷路~
ps:歡迎加入筆者18年建立的研究iOS稽核及前沿技術的三千人扣群:662339934,坑位有限,備註“掘金網友”可被群管通過~
本文正在參加「金石計劃 . 瓜分6萬現金大獎」
- iOS老司機聊聊實際專案開發中的<<人月神話>>
- iOS老司機可落地在中大型iOS專案中的5大接地氣設計模式合集
- iOS老司機的跨端跨平臺Hybrid開發Tips
- iOS老司機的2022年回顧, 聊聊寒冬下的實用<<談判力>>
- iOS老司機可落地的中大型iOS專案中的設計模式優化Tips_橋接模式
- iOS老司機的多執行緒PThread學習分享
- iOS老司機整理, iOSer必會的經典演算法_2
- iOS老司機的<<藍海轉型>>讀書分享
- iOS老司機的<<程式設計師的自我修養:連結、裝載與庫>>讀書分享
- iOS老司機的接地氣演算法Tips
- iOS老司機的RunLoop原理探究及實用Tips
- iOS老司機整理, iOSer必會的經典演算法_1
- iOS老司機的App啟動優化Tips, 讓啟動速度提升10%
- iOS老司機的網路相關Tips
- 戀上資料結構與演算法
- iOS老司機帶你一起把App的崩潰率降到0.1%以下
- 探究Swift的String底層實現
- iOS老司機萬字整理, 可能是最全的Swift Tips
- iOS老司機可落地的中大型iOS專案中的設計模式優化Tips
- 聊一聊Swift中的閉包