iOS開發初探Flutter

一、iOS環境下安裝運行

1.1、運行在模擬器

  • VSCode上,直接點擊調試運行按鈕,選擇Start iOS Simulator;默認會選擇iOS項目中選中的模擬器。


    vsCode.jpg
  • Android Studio上,選擇open iOS Simulator;直接點擊運行。


    Android Studio.png

1.2、運行在iOS真機設備上

  1. 在flutter項目ios目錄下用Xcode打開Runner.xcworkspace,在target設置頁面Signing&Capabilities登錄開發者賬號,配置證書及其配置文件;


    image.png
  2. 若是平常的apple ID登錄的話,后直接運行,安裝至手機會報錯,如若不然需要注冊開發者賬號申請開發證書進行配置。


    error.png
  3. 需要手機信任該開發者證書(設置->通用->描述文件與設備管理)。
    應用打開提示.png
    信任證書.png

    flutter 在macOS上環境搭建

1.2、熱重載

原生開發過程中,無法實現熱重載,每次修改代碼都必須通過(command + R)運行編譯才能對新的代碼調試。
熱重載可以幫助您在無需重新啟動應用的情況下快速、輕松地進行測試、構建用戶界面、添加功能以及修復錯誤; 可以大大提高開發效率。

二、iOS層面上看flutter

2.1、UIView與Widget

在iOS中視圖通常都是也UIView(一般的視圖控件都是繼承UIView)的實例對象來進行構建UI的;對比與Flutter,就好比其中的Widget,但又不能等同視之,UIView是實實在在的一種視圖控件,而Widget我覺得它更像是一種對視圖的申明,或者是作為UI特征的一種描述吧。
1.widget 擁有著不同的生命周期:整個生命周期內它是不可變的,且只能夠存活到被修改的時候。一旦 widget 實例或者它的狀態發生了改變, Flutter 框架就會創建一個新的由 Widget 實例構造而成的樹狀結構。而在 iOS 里,修改一個視圖并不會導致它重新創建實例,它作為一個可變對象,只會繪制一次,只有在發生 setNeedsDisplay() 調用之后才會發生重繪。
2.iOS中,父視圖添加子視圖都是以addSubView來實現的,這個就是會出現每一個視圖整體都是平級,相對獨立的,而widget是通過widget一層一層的嵌套,這就會導致頁面嵌套很多的情況下,代碼非常繁雜,需要對其盡可能的抽取。


iOS視圖.png
flutter.png

3.iOS中,對事件監聽包括手勢事件處理通常使用代理<delegate>或者通知等形式實現的,但是flutter確實包裹一層widget;譬如對scrollview的滾動事件監聽。


NotificationListener.png

4.iOS中,對一些視圖屬性通常都是以參數形式賦予UIView的視圖對象,而在flutter有些需要通過包一層widget來實現,比如透明度。
opacity.png

5.約束布局,iOS的autolaout 在flutter中以padding參數體現。
6.動畫,iOS通常以動畫塊的形式體現,而在 Flutter 中,使用動畫庫來包裹 widgets,而不是創建一個動畫 widget。

2.2、導航/路由

在 iOS 中,你可以使用管理了 view controller 棧的 UINavigationController 來在不同的 view controller 之間跳轉。
Flutter 也有類似的實現,使用了 NavigatorRoutes。一個路由是 App 中“屏幕”或“頁面”的抽象,而一個 Navigator 是管理多個路由的 widget。你可以粗略地把一個路由對應到一個 UIViewController。Navigator 的工作原理和 iOS 中 UINavigationController 非常相似,當你想跳轉到新頁面或者從新頁面返回時,它可以 push()pop() 路由。
但是,個人認為這樣的路由是否頁面繁多情況下會非常龐大,是有有可改進地方<問題>。
另外,通常iOS導航欄高度都是44,而在flutter中默認高度都是56。

2.3、圖片資源

在iOS中,把通常把圖片放于assets文件夾或者bundle目錄下,assets里面有區分1x、2x、3x等幾倍圖,根據手機分辨率自動調整。
在flutter中,必須在 pubspec.yaml 文件中聲明 assets (和位置),然后 Flutter 會把他們識別出來。


pubspec.png

把基礎圖片(1.0x)放置到 images 文件夾中,并把其他變體放置在子文件夾中,并接上合適的比例系數:


image.png

2.4、數據庫和本地存儲

  1. 我怎么在 Flutter 中訪問 UserDefaults?
    在 iOS 中,你可以使用屬性列表來存儲鍵值對的集合,即我們熟悉的 UserDefaults。
    在 Flutter 中,可以使用 Shared Preferences plugin來達到相似的功能。它包裹了 UserDefaluts 以及 Android 上等價的 SharedPreferences 的功能。
  2. CoreData 相當于 Flutter 中的什么?
    在 iOS 中,你通過 CoreData 來存儲結構化的數據。這是一個 SQL 數據庫的上層封裝,讓查詢和關聯模型變得更加簡單。
    在 Flutter 中,使用 SQFlite 插件來實現這個功能。

具體可以看flutter中文網

三、flutter與iOS原生交互

我們都知道Flutter開發的app是可以同時在iOS和Android系統上運行的。顯然Flutter需要有和Native通信的能力。比如說,你的Flutter app要顯示手機的電量,而電量只能通過平臺的系統Api獲取。這時就需要有個機制使得Flutter可以通過某種方式來調用這個系統Api并且獲得返回值。那么Flutter是通過Platform Channels(平臺通道)做到的。


Platform Channels的架構示意圖.png

Platform channel通信的三種類型:

BasicMessageChannel:用于傳遞字符串和半結構化的信息,持續通信,收到消息后可以回復此次消息,如:Native將遍歷到的文件信息陸續傳遞到dart,在比如:flutter將從服務端陸續獲取到的信息交給Native加工,Native處理完返回等。
MethodChannel:用于傳遞方法調用(method invocation)一次性通信:如flutter調用Native拍照。
EventChannel:用于數據流(event stream)的通信,持續通信,收到消息后無法回復此次消息,通過長用于Nativie向flutter的通信,如:手機電量變化,網絡連接變化,陀螺儀,傳感器等;
這三種類型的Channel都是全雙工通信,即A<=>B,flutter可以主動發送消息給Native端,并且Native接收到消息后可以做出回應,同樣,Native端可以主動發送消息給flutter端,flutter端接收數據后給Native端。
參考:http://www.imooc.com/article/286076?block_id=tuijian_wz
Flutter和原生iOS交互:http://www.lxweimin.com/p/5e5d54db8c7e
flutter學習筆記:自定義相機http://www.lxweimin.com/p/c4d7c189ba78
總而言之,flutter所展示的頁面內容其實是iOS中一個叫FlutterViewController的視圖控制器,所以起調用原生頁面也必須通過這個控制器進行跳轉,是通過FlutterMethodChannel建立通道調用原生方法,這一點其實是跟WKWebView與js交互,調用原生方法是類似的。

四、構建打包

打包過程跟原生開發時打包是完全一樣的,需要注意一下內容:
1.appIcon必須在Xcode里面進行設置,放于Assets.xcassets文件夾中。具體規則需按照要求的尺寸設置。
2.app兼容最低版本設置:Deployment Target。
3.所要用到的設備里面的權限需要在info.plist文件中配置清楚。


Target.png

info.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。