SlideShare a Scribd company logo
1 of 41
Download to read offline
Flutter 踩雷雷⼼心得
楊維中 a.k.a zonble

wzyang@kkbox.com
簡介
• 在 KKBOX 的⼯工程師,之前都在做 KKBOX 在各種蘋果平台
上的版本,包括 iOS、macOS、tvOS 以及 watchOS

• 今年年五⽉月在 KKBOX 成⽴立新部⾨門,部⾨門名稱叫做
eXperimental Design and Development Division - XDDD,
只有兩個⼈人,開發新的實驗性產品

• 因為只有兩個⼈人,因此就會想要研究⼀一些跨平台的 App 開
發框架,並且在今年年七⽉月起在 KKBOX 導⼊入 Flutter
⼤大綱
• 什什麼是 Flutter

• 軟體⼯工程⽅方⾯面的雜談

• 發⾏行行

• 編譯

• 測試

• 團隊組成
Flutter 是什什麼?🤔
• 設計給 Google ⼀一套尚未正式推出的作業系統 Fuchsia 使⽤用
的應⽤用程式框架

• ⽬目前可以被嵌⼊入在 iOS 與 Android app 中執⾏行行,因此也就
成為⼀一套跨平台的應⽤用程式框架

• 架構上,很像是精簡過的瀏覽器器,⽽而在現在的硬體上,有
不不輸給 Native App Framework 的流暢程度
瀏覽器器的組成
• HTML loader:發送 HTTP 連線,抓取 HTML、CSS 檔案

• HTML Parser:將 HTML 解析成 DOM 物件樹

• DOM:⾴頁⾯面元件的 model 物件

• Renderer:將 DOM 繪製到畫⾯面中

• JavaScript Engine:使⽤用 JS 撰寫額外的邏輯,以及操作
DOM,像是加⼊入/刪除節點
Flutter 的組成
• Widget:組成畫⾯面的樹狀狀結構

• Stateless Widget:建⽴立之後不不會改動的 Widget

• Stateful Widget:建⽴立之後可以改變內部狀狀態的 Widget

• Renderer:將 Widget 畫出來來

• Dart VM:⽤用來來組成 Widget 的程式語⾔言 runtime

直接使⽤用 code 組出 Widget,不不需要像 HTML tag 這種還要額外解
析的語法
寫起 Flutter 的感覺
• 基本上,就是⾃自⼰己組出 Widget 樹給 Renderer 繪製。沒有
MVC 之分,全都是 view model

• ⾮非常接近 Web 開發中的 SPA,寫過 React、Vue 的⼈人,應
該會對 Flutter 覺得有點親切
拿 Flutter 做產品?
• 越接近 Web app 的 Mobile app,越適合使⽤用 Flutter 開發

• Flutter 專⻑⾧長處理理複雜的 UI 排版,像是⼀一些複雜的表格、圖
⽂文整合的故事⾴頁⾯面,不不同螢幕尺⼨寸要⽤用不不同的版⾯面…⽤用
Native Framework 反⽽而很難做

• 適合像是新聞、電商、聊天室等軟體
Flutter 不不適合
• 遊戲:Flutter 基本上不不⿎鼓勵勵⼀一直做畫⾯面的重繪

• 需要⽤用到平台或硬體功能的 app:拍照、錄錄影、錄錄⾳音、媒
體串串流

• 在 iOS 上,你會捨棄 3D Touch、與 watchOS 或其他 iOS
widget 共⽤用 framework 

• 需要⼤大量量運算的功能
⽬目前的 Flutter 某些地⽅方還有問題
• 多國語⾔言⽀支援:Dart 的 Localization Engine 只去抓
Language code 與 Country code,所以 iOS 上使⽤用 zh-
Hant,只能抓到 zh,最近才改 (Flutter PR #23583)

• 在 iOS 12 ,中⽂文預設使⽤用很奇怪的明體字…
導⼊入 Flutter 之後 🤔
• 我們還要懂 Native 開發嗎?
• 我們還需要 iOS/Android ⼯工程師嗎?
…我常常被問
• 你還是要懂 iOS/Android 開發
• 但,如果你
• 原本就有熟練的 iOS/Android ⼯工程師
• 做好前置作業
• Flutter 可以節省很多時間與⼒力力氣
導⼊入 Flutter
• 開發

• Dart 程式語⾔言

• 認識 Flutter Widget

• 習慣 Flutter Pattern(如⼤大量量使⽤用 Decorator)

• …知道 Flutter 原廠還有哪些 Bug

• Flutter Plug-in 開發

• Build System

• 測試
Build Flutter Apps
發⾏行行版本號碼管理理
• Flutter 預設 iOS/Android App 共⽤用同⼀一個寫在
pubspec.yml 檔案中的版號

• iOS 會寫⼊入到 Info.plist 中

• Anrdrod 會寫⼊入到 gradle 設定中

• 在呼叫 flutter build 指令時,可以指定 —build-name 與 —
build-number

• iOS 正常,Android 就莫名其妙不不⾏行行
編譯流程
• 兩段式的編譯

• 先將 Dart code 編譯成 native code

• 然後

• iOS:拉 Cocoa Pods、在 app bundle 中嵌⼊入 Flutter
framework、編譯 ObjC/Swift code、打包、code sign

• Android:啟動 gradle、安裝 Dependencies 、編譯
Java/Kotlin、proguard、sign APK
混淆 Dart code
• 官⽅方提供⼀一套 Dart Obfuscator

• 但是⽂文件說,還沒有完整測試過

• 在我們⾃自⼰己的專案中,⼀一混淆了了 Dart code,整個 app 跑起
來來就當掉了了…🤣
Flutter 不不⽀支援 Xcode 10 的
New Build System
Dependency 管理理
• Flutter 使⽤用 dart pub 管理理套件,但是如果⼀一個 plugin ⽤用到
了了 device channel,iOS ⽤用 CocoaPods 管理理,Android 使⽤用
gradle

• iOS:可能每個 plugin 的 deployment target 不不⼀一樣,需要
⾃自⼰己調整 pod 設定

• Android:可能每個 plugin 使⽤用的 Android API、Kotlin、
Google Service 版本不不同⽽而發⽣生衝突

• 所以你還是要有⼈人懂這些
Android 的 32/64 問題
• Flutter 還不不⽀支援 Android App Bundle

• ⼀一次只會編譯 32 或 64 的 libflutter.so

• 開發版本中,可以⽤用 CLI 編出兩種版本

• flutter build apk --debug --target-platform android-arm

• flutter build apk --debug --target-platform android-arm64

• Release 版本⽬目前先只保留留 armv7a 的 NDK…
X86 Android
• Flutter 沒有 X86 的 Release Binary

• 但是外⾯面有

• 以卵卵擊⽯石的 x86 Android ⼿手機

• Chromebook

• …去 Google Play 後台禁⽌止這些裝置下載你的 app
環境的版本
• Flutter/Dart 的版本:Dart Pub 上現在很多 package 不不知
元 Dart 2…

• Xcode/iOS SDK 版本:Flutter 還不不⽀支援 Xcode 10 的 New
Build System…

• Android 版本問題:要使⽤用那種 Android SDK?每個 plugin
使⽤用的是哪種 gradle/Kotlin 版本?

• 其中⼀一者發⽣生改動,就整個團隊要更更新開發環境
CI
• MS App Center 還不不⽀支援 Flutter app 的設定

• Travis CI 應該要可以,但我搞不不起來來

• 常常遇到無法偵測抓下來來的 flutter runtime 的版本,導致
無法更更新 dependency(pub get 失敗)

• …我們還是在⽤用 Jenkins
Testing
• 使⽤用 Flutter 開發,就等於是跟 XCTest、XCUITest 等框架
說再⾒見見了了

• Flutter 有兩種測試框架:

• Dart 的單元測試

• Flutter Widget 測試
Dart 單元測試
• 如果是可以獨⽴立運作的 code,建議改寫成獨⽴立的 Dart
package(可以⽤用 stagehand 建⽴立)

• 使⽤用 Flutter 或是直接⽤用獨⽴立的 Dart VM 跑測試都可以,但
是 Flutter 裡頭的⼯工具⽐比較好

• 有 Mockito 做 Mock

• …我直接⽤用 Dart VM 跑測試,怎樣都搞不不出覆蓋率報告出
來來
Widget 測試
• 可以把整個 app 的根 widget 跑起來來,或是單獨將⼀一個
widget 包進⼀一個 app 容器器裡頭測試。檢查⼀一些⾏行行為之後,
畫⾯面中是否有出現對應的 widget

• 不不好寫:Flutter 基本上禁⽌止在結束測試的時候,widget 當
中還有⾮非同步的 code 在執⾏行行,會丟出 exception

• ⼀一個可以跑 Widget Test 的 Widget,基本上要把所有⾮非同
步的操作都 mock 掉
⼀一些東⻄西無法測試
• Flutter app 與 plug-in/device channel 之間的溝通
線上問題的處理理
• 如果在 Dart VM 裡頭發⽣生邏輯錯誤,不不會產⽣生 crash log 回
報,只會直接在 app 裡頭畫出紅畫⾯面,在發⽣生問題時,增
加解決問題的難度

• Flutter 的 exception 往往也不不會直接告訴你在 code 的哪
段,⽽而是 renderer 當中丟出的 exception

• 有些事情你想不不到:在 ListView 裡頭使⽤用 StatefulWidget
會跳出 Exception…
開始導⼊入 Flutter
建議在新專案導⼊入 Flutter
• 在原本的 iOS/Android app 上導⼊入 Flutter,技術上可⾏行行,
iOS/Android app 可以嵌⼊入 Flutter view。

• 但是軟體⼯工程上很麻煩

• Flutter app 要求將跨平台的 code/平台專屬的 code 區隔
開來來,在軟體架構上相當具有挑戰

• 平台專屬的 code 也要維持同⼀一個介⾯面,讓 Dart code 可
以呼叫,也就是,iOS/Android app 基本上要使⽤用同⼀一套
架構設計
團隊的組成
• 基本上要有夠資深的 iOS/Android ⼯工程師

• 搞定 codesign、發⾏行行上架等問題

• 要每個⼯工程師同時懂兩個平台很難

• 下⼀一步,就是這兩個⼯工程師應該還要有各⾃自的代理理,之後可以加⼊入
只寫 Dart 的⼈人

• 先以⼤大量量的單元測試加上 QA ⼿手動測試為主

• 因為 Flutter 的 Widget Test 實在很難寫,⽽而且有地⽅方還測不不到…
改變思維
• Flutter 的 Controller 不不是 iOS 的 Controller

• iOS 的 Controller 是畫⾯面的基本單位

• Flutter 的 Widget ⾃自成天地,當外部想操作某個 Widget 時,才提供
⼀一個 Controller 當做接⼝口

• Flutter 的 delegate 不不是 iOS 的 delegate

• iOS 的 delegate 是集中處理理 callback 的物件,在 Flutter 中則使⽤用
builder function 或是 

• Flutter 的 delegate 像是 Widget 的設定
改變思維
• 在 iOS 上,如果有個連線,我們可能會在 ViewController
中呼叫 NSURLSession 以及 NSURLSessionTask

• 在 Flutter 中,我們的作法可能是把⽤用到這個連線的畫⾯面⽤用
FutureBuilder 包起來來

• <Furture><Widget>….</Future>
換台新電腦
• 你可能會同時開

• Android Studio

• Xcode

• Android Emulator

• iOS Simulator

• 其他編輯器器…
⼯工商服務時間
Recap
• 什什麼是 Flutter

• 軟體⼯工程⽅方⾯面的雜談

• 發⾏行行

• 編譯

• 測試

• 團隊組成
以上

More Related Content

What's hot

Docker introduction
Docker introductionDocker introduction
Docker introductiondotCloud
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園Shengyou Fan
 
Docker introduction (1)
Docker introduction (1)Docker introduction (1)
Docker introduction (1)Gourav Varma
 
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台Shengyou Fan
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率Shengyou Fan
 
55 New Features in Java SE 8
55 New Features in Java SE 855 New Features in Java SE 8
55 New Features in Java SE 8Simon Ritter
 
Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)lestrrat
 
Kotlin Jetpack Tutorial
Kotlin Jetpack TutorialKotlin Jetpack Tutorial
Kotlin Jetpack TutorialSimplilearn
 
實現 Angular, Docker 與 Kubernetes 持續部署 (NG+2020)
實現 Angular, Docker 與 Kubernetes 持續部署 (NG+2020)實現 Angular, Docker 與 Kubernetes 持續部署 (NG+2020)
實現 Angular, Docker 與 Kubernetes 持續部署 (NG+2020)Will Huang
 
Intro to vue.js
Intro to vue.jsIntro to vue.js
Intro to vue.jsTechMagic
 
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇Shengyou Fan
 
Java SE 8 技術手冊第 2 章 - 從JDK到IDE
Java SE 8 技術手冊第 2 章 - 從JDK到IDEJava SE 8 技術手冊第 2 章 - 從JDK到IDE
Java SE 8 技術手冊第 2 章 - 從JDK到IDEJustin Lin
 
Introduction to docker
Introduction to dockerIntroduction to docker
Introduction to dockerJohn Willis
 

What's hot (20)

Docker
DockerDocker
Docker
 
Docker introduction
Docker introductionDocker introduction
Docker introduction
 
Arquitetura do Framework Spring
Arquitetura do Framework SpringArquitetura do Framework Spring
Arquitetura do Framework Spring
 
[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園[COSCUP 2022] Kotlin Collection 遊樂園
[COSCUP 2022] Kotlin Collection 遊樂園
 
Docker introduction (1)
Docker introduction (1)Docker introduction (1)
Docker introduction (1)
 
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
[MOPCON 2022] 以 Kotlin Multiplatform 制霸全平台
 
Hibernate jpa
Hibernate jpaHibernate jpa
Hibernate jpa
 
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
簡化 JVM 上雲 - 透過 Azure Spring Cloud 提升開發、發佈及服務監控效率
 
55 New Features in Java SE 8
55 New Features in Java SE 855 New Features in Java SE 8
55 New Features in Java SE 8
 
Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)
 
Ionic Framework
Ionic FrameworkIonic Framework
Ionic Framework
 
Flutter Rennes - #1
Flutter Rennes - #1Flutter Rennes - #1
Flutter Rennes - #1
 
Kotlin Jetpack Tutorial
Kotlin Jetpack TutorialKotlin Jetpack Tutorial
Kotlin Jetpack Tutorial
 
實現 Angular, Docker 與 Kubernetes 持續部署 (NG+2020)
實現 Angular, Docker 與 Kubernetes 持續部署 (NG+2020)實現 Angular, Docker 與 Kubernetes 持續部署 (NG+2020)
實現 Angular, Docker 與 Kubernetes 持續部署 (NG+2020)
 
Intro to vue.js
Intro to vue.jsIntro to vue.js
Intro to vue.js
 
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
[JCConf 2022] Compose for Desktop - 開發桌面軟體的新選擇
 
Docker, LinuX Container
Docker, LinuX ContainerDocker, LinuX Container
Docker, LinuX Container
 
Docker swarm
Docker swarmDocker swarm
Docker swarm
 
Java SE 8 技術手冊第 2 章 - 從JDK到IDE
Java SE 8 技術手冊第 2 章 - 從JDK到IDEJava SE 8 技術手冊第 2 章 - 從JDK到IDE
Java SE 8 技術手冊第 2 章 - 從JDK到IDE
 
Introduction to docker
Introduction to dockerIntroduction to docker
Introduction to docker
 

Similar to Flutter 踩雷心得

GDG Taichung - Flutter and Firebase.pdf
GDG Taichung - Flutter and Firebase.pdfGDG Taichung - Flutter and Firebase.pdf
GDG Taichung - Flutter and Firebase.pdfDuran Hsieh
 
Build desktop app_by_xulrunner
Build desktop app_by_xulrunnerBuild desktop app_by_xulrunner
Build desktop app_by_xulrunnerRack Lin
 
打造你專屬的Xcode plugin
打造你專屬的Xcode plugin打造你專屬的Xcode plugin
打造你專屬的Xcode pluginYuhua Chen
 
專案啟動與設定
專案啟動與設定專案啟動與設定
專案啟動與設定Shengyou Fan
 
Phonegap入門
Phonegap入門Phonegap入門
Phonegap入門Roy Chen
 
钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具taobao.com
 
Composer 套件管理
Composer 套件管理Composer 套件管理
Composer 套件管理Shengyou Fan
 
[2020 .NET Conf] 企業Azure DevOps Service 實際應用架構與秘辛
[2020 .NET Conf] 企業Azure DevOps Service 實際應用架構與秘辛[2020 .NET Conf] 企業Azure DevOps Service 實際應用架構與秘辛
[2020 .NET Conf] 企業Azure DevOps Service 實際應用架構與秘辛Edward Kuo
 
Weic2015 docker
Weic2015 dockerWeic2015 docker
Weic2015 dockerRay Lin
 
Java Build Tool course in 2011
Java Build Tool course in 2011Java Build Tool course in 2011
Java Build Tool course in 2011Ching Yi Chan
 
Docker技术介绍
Docker技术介绍Docker技术介绍
Docker技术介绍LI jeanphorn
 
React Native & V2HOT
React Native & V2HOTReact Native & V2HOT
React Native & V2HOTXcat Liu
 
開放原始碼 Ch2.1 app - oss - oss ide (ver1.2)
開放原始碼 Ch2.1   app - oss - oss ide (ver1.2)開放原始碼 Ch2.1   app - oss - oss ide (ver1.2)
開放原始碼 Ch2.1 app - oss - oss ide (ver1.2)My own sweet home!
 
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境Will Huang
 
VSCode Remote Development 介紹
VSCode Remote Development 介紹VSCode Remote Development 介紹
VSCode Remote Development 介紹Philip Zheng
 
VSCode Remote Development
VSCode Remote DevelopmentVSCode Remote Development
VSCode Remote DevelopmentPhilip Zheng
 

Similar to Flutter 踩雷心得 (20)

GDG Taichung - Flutter and Firebase.pdf
GDG Taichung - Flutter and Firebase.pdfGDG Taichung - Flutter and Firebase.pdf
GDG Taichung - Flutter and Firebase.pdf
 
Docker基礎
Docker基礎Docker基礎
Docker基礎
 
Build desktop app_by_xulrunner
Build desktop app_by_xulrunnerBuild desktop app_by_xulrunner
Build desktop app_by_xulrunner
 
打造你專屬的Xcode plugin
打造你專屬的Xcode plugin打造你專屬的Xcode plugin
打造你專屬的Xcode plugin
 
專案啟動與設定
專案啟動與設定專案啟動與設定
專案啟動與設定
 
Phonegap入門
Phonegap入門Phonegap入門
Phonegap入門
 
钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具
 
Composer 套件管理
Composer 套件管理Composer 套件管理
Composer 套件管理
 
[2020 .NET Conf] 企業Azure DevOps Service 實際應用架構與秘辛
[2020 .NET Conf] 企業Azure DevOps Service 實際應用架構與秘辛[2020 .NET Conf] 企業Azure DevOps Service 實際應用架構與秘辛
[2020 .NET Conf] 企業Azure DevOps Service 實際應用架構與秘辛
 
Weic2015 docker
Weic2015 dockerWeic2015 docker
Weic2015 docker
 
Flutter實作概述 | GDSC NYCU
Flutter實作概述 | GDSC NYCUFlutter實作概述 | GDSC NYCU
Flutter實作概述 | GDSC NYCU
 
Java Build Tool course in 2011
Java Build Tool course in 2011Java Build Tool course in 2011
Java Build Tool course in 2011
 
Docker技术介绍
Docker技术介绍Docker技术介绍
Docker技术介绍
 
React Native & V2HOT
React Native & V2HOTReact Native & V2HOT
React Native & V2HOT
 
iOS
iOSiOS
iOS
 
Android工作坊
Android工作坊Android工作坊
Android工作坊
 
開放原始碼 Ch2.1 app - oss - oss ide (ver1.2)
開放原始碼 Ch2.1   app - oss - oss ide (ver1.2)開放原始碼 Ch2.1   app - oss - oss ide (ver1.2)
開放原始碼 Ch2.1 app - oss - oss ide (ver1.2)
 
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境從頭打造 C#、.NET 與 ASP.NET Core 開發環境
從頭打造 C#、.NET 與 ASP.NET Core 開發環境
 
VSCode Remote Development 介紹
VSCode Remote Development 介紹VSCode Remote Development 介紹
VSCode Remote Development 介紹
 
VSCode Remote Development
VSCode Remote DevelopmentVSCode Remote Development
VSCode Remote Development
 

More from Weizhong Yang

怎樣在 Flutter app 中使用 Google Maps
怎樣在 Flutter app 中使用 Google Maps怎樣在 Flutter app 中使用 Google Maps
怎樣在 Flutter app 中使用 Google MapsWeizhong Yang
 
關於延長役期這件事情
關於延長役期這件事情關於延長役期這件事情
關於延長役期這件事情Weizhong Yang
 
iPlayground: CarPlay and MFI Hearing Aids
iPlayground: CarPlay and MFI Hearing AidsiPlayground: CarPlay and MFI Hearing Aids
iPlayground: CarPlay and MFI Hearing AidsWeizhong Yang
 
CocoaPods private repo
CocoaPods private repoCocoaPods private repo
CocoaPods private repoWeizhong Yang
 
那些年被蘋果 Ban 掉的 API
那些年被蘋果 Ban 掉的 API那些年被蘋果 Ban 掉的 API
那些年被蘋果 Ban 掉的 APIWeizhong Yang
 
給 iOS 工程師的 Vue.js 開發
給 iOS 工程師的 Vue.js 開發給 iOS 工程師的 Vue.js 開發
給 iOS 工程師的 Vue.js 開發Weizhong Yang
 
苦集滅道:透過開發客製 Sketch Plug-in 改善產品設計流程
苦集滅道:透過開發客製 Sketch Plug-in  改善產品設計流程苦集滅道:透過開發客製 Sketch Plug-in  改善產品設計流程
苦集滅道:透過開發客製 Sketch Plug-in 改善產品設計流程Weizhong Yang
 
使用 switch/case 重構程式碼
使用 switch/case 重構程式碼使用 switch/case 重構程式碼
使用 switch/case 重構程式碼Weizhong Yang
 
怎樣寫出比較沒有問題的 Code
怎樣寫出比較沒有問題的 Code怎樣寫出比較沒有問題的 Code
怎樣寫出比較沒有問題的 CodeWeizhong Yang
 
Aspect Oriented Programming
Aspect Oriented ProgrammingAspect Oriented Programming
Aspect Oriented ProgrammingWeizhong Yang
 
Mac OS X 與 iOS 的 Audio API
Mac OS X 與 iOS 的 Audio APIMac OS X 與 iOS 的 Audio API
Mac OS X 與 iOS 的 Audio APIWeizhong Yang
 
Python 的文件系統
Python 的文件系統Python 的文件系統
Python 的文件系統Weizhong Yang
 

More from Weizhong Yang (20)

Flutter BLE
Flutter BLEFlutter BLE
Flutter BLE
 
怎樣在 Flutter app 中使用 Google Maps
怎樣在 Flutter app 中使用 Google Maps怎樣在 Flutter app 中使用 Google Maps
怎樣在 Flutter app 中使用 Google Maps
 
關於延長役期這件事情
關於延長役期這件事情關於延長役期這件事情
關於延長役期這件事情
 
Dart null safety
Dart null safetyDart null safety
Dart null safety
 
Github Actions
Github ActionsGithub Actions
Github Actions
 
iPlayground: CarPlay and MFI Hearing Aids
iPlayground: CarPlay and MFI Hearing AidsiPlayground: CarPlay and MFI Hearing Aids
iPlayground: CarPlay and MFI Hearing Aids
 
CocoaPods private repo
CocoaPods private repoCocoaPods private repo
CocoaPods private repo
 
那些年被蘋果 Ban 掉的 API
那些年被蘋果 Ban 掉的 API那些年被蘋果 Ban 掉的 API
那些年被蘋果 Ban 掉的 API
 
給 iOS 工程師的 Vue.js 開發
給 iOS 工程師的 Vue.js 開發給 iOS 工程師的 Vue.js 開發
給 iOS 工程師的 Vue.js 開發
 
苦集滅道:透過開發客製 Sketch Plug-in 改善產品設計流程
苦集滅道:透過開發客製 Sketch Plug-in  改善產品設計流程苦集滅道:透過開發客製 Sketch Plug-in  改善產品設計流程
苦集滅道:透過開發客製 Sketch Plug-in 改善產品設計流程
 
使用 switch/case 重構程式碼
使用 switch/case 重構程式碼使用 switch/case 重構程式碼
使用 switch/case 重構程式碼
 
怎樣寫出比較沒有問題的 Code
怎樣寫出比較沒有問題的 Code怎樣寫出比較沒有問題的 Code
怎樣寫出比較沒有問題的 Code
 
貪食蛇
貪食蛇貪食蛇
貪食蛇
 
Aspect Oriented Programming
Aspect Oriented ProgrammingAspect Oriented Programming
Aspect Oriented Programming
 
Mac OS X 與 iOS 的 Audio API
Mac OS X 與 iOS 的 Audio APIMac OS X 與 iOS 的 Audio API
Mac OS X 與 iOS 的 Audio API
 
Html 5 native drag
Html 5 native dragHtml 5 native drag
Html 5 native drag
 
Retina mac
Retina macRetina mac
Retina mac
 
Python 的文件系統
Python 的文件系統Python 的文件系統
Python 的文件系統
 
Input Method Kit
Input Method KitInput Method Kit
Input Method Kit
 
Refactoring
RefactoringRefactoring
Refactoring
 

Flutter 踩雷心得

  • 2.
  • 3. 簡介 • 在 KKBOX 的⼯工程師,之前都在做 KKBOX 在各種蘋果平台 上的版本,包括 iOS、macOS、tvOS 以及 watchOS • 今年年五⽉月在 KKBOX 成⽴立新部⾨門,部⾨門名稱叫做 eXperimental Design and Development Division - XDDD, 只有兩個⼈人,開發新的實驗性產品 • 因為只有兩個⼈人,因此就會想要研究⼀一些跨平台的 App 開 發框架,並且在今年年七⽉月起在 KKBOX 導⼊入 Flutter
  • 4.
  • 5.
  • 6. ⼤大綱 • 什什麼是 Flutter • 軟體⼯工程⽅方⾯面的雜談 • 發⾏行行 • 編譯 • 測試 • 團隊組成
  • 7. Flutter 是什什麼?🤔 • 設計給 Google ⼀一套尚未正式推出的作業系統 Fuchsia 使⽤用 的應⽤用程式框架 • ⽬目前可以被嵌⼊入在 iOS 與 Android app 中執⾏行行,因此也就 成為⼀一套跨平台的應⽤用程式框架 • 架構上,很像是精簡過的瀏覽器器,⽽而在現在的硬體上,有 不不輸給 Native App Framework 的流暢程度
  • 8. 瀏覽器器的組成 • HTML loader:發送 HTTP 連線,抓取 HTML、CSS 檔案 • HTML Parser:將 HTML 解析成 DOM 物件樹 • DOM:⾴頁⾯面元件的 model 物件 • Renderer:將 DOM 繪製到畫⾯面中 • JavaScript Engine:使⽤用 JS 撰寫額外的邏輯,以及操作 DOM,像是加⼊入/刪除節點
  • 9. Flutter 的組成 • Widget:組成畫⾯面的樹狀狀結構 • Stateless Widget:建⽴立之後不不會改動的 Widget • Stateful Widget:建⽴立之後可以改變內部狀狀態的 Widget • Renderer:將 Widget 畫出來來 • Dart VM:⽤用來來組成 Widget 的程式語⾔言 runtime 直接使⽤用 code 組出 Widget,不不需要像 HTML tag 這種還要額外解 析的語法
  • 10. 寫起 Flutter 的感覺 • 基本上,就是⾃自⼰己組出 Widget 樹給 Renderer 繪製。沒有 MVC 之分,全都是 view model • ⾮非常接近 Web 開發中的 SPA,寫過 React、Vue 的⼈人,應 該會對 Flutter 覺得有點親切
  • 11. 拿 Flutter 做產品? • 越接近 Web app 的 Mobile app,越適合使⽤用 Flutter 開發 • Flutter 專⻑⾧長處理理複雜的 UI 排版,像是⼀一些複雜的表格、圖 ⽂文整合的故事⾴頁⾯面,不不同螢幕尺⼨寸要⽤用不不同的版⾯面…⽤用 Native Framework 反⽽而很難做 • 適合像是新聞、電商、聊天室等軟體
  • 12. Flutter 不不適合 • 遊戲:Flutter 基本上不不⿎鼓勵勵⼀一直做畫⾯面的重繪 • 需要⽤用到平台或硬體功能的 app:拍照、錄錄影、錄錄⾳音、媒 體串串流 • 在 iOS 上,你會捨棄 3D Touch、與 watchOS 或其他 iOS widget 共⽤用 framework • 需要⼤大量量運算的功能
  • 13. ⽬目前的 Flutter 某些地⽅方還有問題 • 多國語⾔言⽀支援:Dart 的 Localization Engine 只去抓 Language code 與 Country code,所以 iOS 上使⽤用 zh- Hant,只能抓到 zh,最近才改 (Flutter PR #23583) • 在 iOS 12 ,中⽂文預設使⽤用很奇怪的明體字…
  • 14. 導⼊入 Flutter 之後 🤔 • 我們還要懂 Native 開發嗎? • 我們還需要 iOS/Android ⼯工程師嗎? …我常常被問
  • 15. • 你還是要懂 iOS/Android 開發 • 但,如果你 • 原本就有熟練的 iOS/Android ⼯工程師 • 做好前置作業 • Flutter 可以節省很多時間與⼒力力氣
  • 16. 導⼊入 Flutter • 開發 • Dart 程式語⾔言 • 認識 Flutter Widget • 習慣 Flutter Pattern(如⼤大量量使⽤用 Decorator) • …知道 Flutter 原廠還有哪些 Bug • Flutter Plug-in 開發 • Build System • 測試
  • 18. 發⾏行行版本號碼管理理 • Flutter 預設 iOS/Android App 共⽤用同⼀一個寫在 pubspec.yml 檔案中的版號 • iOS 會寫⼊入到 Info.plist 中 • Anrdrod 會寫⼊入到 gradle 設定中 • 在呼叫 flutter build 指令時,可以指定 —build-name 與 — build-number • iOS 正常,Android 就莫名其妙不不⾏行行
  • 19. 編譯流程 • 兩段式的編譯 • 先將 Dart code 編譯成 native code • 然後 • iOS:拉 Cocoa Pods、在 app bundle 中嵌⼊入 Flutter framework、編譯 ObjC/Swift code、打包、code sign • Android:啟動 gradle、安裝 Dependencies 、編譯 Java/Kotlin、proguard、sign APK
  • 20. 混淆 Dart code • 官⽅方提供⼀一套 Dart Obfuscator • 但是⽂文件說,還沒有完整測試過 • 在我們⾃自⼰己的專案中,⼀一混淆了了 Dart code,整個 app 跑起 來來就當掉了了…🤣
  • 21. Flutter 不不⽀支援 Xcode 10 的 New Build System
  • 22. Dependency 管理理 • Flutter 使⽤用 dart pub 管理理套件,但是如果⼀一個 plugin ⽤用到 了了 device channel,iOS ⽤用 CocoaPods 管理理,Android 使⽤用 gradle • iOS:可能每個 plugin 的 deployment target 不不⼀一樣,需要 ⾃自⼰己調整 pod 設定 • Android:可能每個 plugin 使⽤用的 Android API、Kotlin、 Google Service 版本不不同⽽而發⽣生衝突 • 所以你還是要有⼈人懂這些
  • 23. Android 的 32/64 問題 • Flutter 還不不⽀支援 Android App Bundle • ⼀一次只會編譯 32 或 64 的 libflutter.so • 開發版本中,可以⽤用 CLI 編出兩種版本 • flutter build apk --debug --target-platform android-arm • flutter build apk --debug --target-platform android-arm64 • Release 版本⽬目前先只保留留 armv7a 的 NDK…
  • 24.
  • 25. X86 Android • Flutter 沒有 X86 的 Release Binary • 但是外⾯面有 • 以卵卵擊⽯石的 x86 Android ⼿手機 • Chromebook • …去 Google Play 後台禁⽌止這些裝置下載你的 app
  • 26. 環境的版本 • Flutter/Dart 的版本:Dart Pub 上現在很多 package 不不知 元 Dart 2… • Xcode/iOS SDK 版本:Flutter 還不不⽀支援 Xcode 10 的 New Build System… • Android 版本問題:要使⽤用那種 Android SDK?每個 plugin 使⽤用的是哪種 gradle/Kotlin 版本? • 其中⼀一者發⽣生改動,就整個團隊要更更新開發環境
  • 27. CI • MS App Center 還不不⽀支援 Flutter app 的設定 • Travis CI 應該要可以,但我搞不不起來來 • 常常遇到無法偵測抓下來來的 flutter runtime 的版本,導致 無法更更新 dependency(pub get 失敗) • …我們還是在⽤用 Jenkins
  • 28. Testing • 使⽤用 Flutter 開發,就等於是跟 XCTest、XCUITest 等框架 說再⾒見見了了 • Flutter 有兩種測試框架: • Dart 的單元測試 • Flutter Widget 測試
  • 29. Dart 單元測試 • 如果是可以獨⽴立運作的 code,建議改寫成獨⽴立的 Dart package(可以⽤用 stagehand 建⽴立) • 使⽤用 Flutter 或是直接⽤用獨⽴立的 Dart VM 跑測試都可以,但 是 Flutter 裡頭的⼯工具⽐比較好 • 有 Mockito 做 Mock • …我直接⽤用 Dart VM 跑測試,怎樣都搞不不出覆蓋率報告出 來來
  • 30. Widget 測試 • 可以把整個 app 的根 widget 跑起來來,或是單獨將⼀一個 widget 包進⼀一個 app 容器器裡頭測試。檢查⼀一些⾏行行為之後, 畫⾯面中是否有出現對應的 widget • 不不好寫:Flutter 基本上禁⽌止在結束測試的時候,widget 當 中還有⾮非同步的 code 在執⾏行行,會丟出 exception • ⼀一個可以跑 Widget Test 的 Widget,基本上要把所有⾮非同 步的操作都 mock 掉
  • 31. ⼀一些東⻄西無法測試 • Flutter app 與 plug-in/device channel 之間的溝通
  • 32. 線上問題的處理理 • 如果在 Dart VM 裡頭發⽣生邏輯錯誤,不不會產⽣生 crash log 回 報,只會直接在 app 裡頭畫出紅畫⾯面,在發⽣生問題時,增 加解決問題的難度 • Flutter 的 exception 往往也不不會直接告訴你在 code 的哪 段,⽽而是 renderer 當中丟出的 exception • 有些事情你想不不到:在 ListView 裡頭使⽤用 StatefulWidget 會跳出 Exception…
  • 34. 建議在新專案導⼊入 Flutter • 在原本的 iOS/Android app 上導⼊入 Flutter,技術上可⾏行行, iOS/Android app 可以嵌⼊入 Flutter view。 • 但是軟體⼯工程上很麻煩 • Flutter app 要求將跨平台的 code/平台專屬的 code 區隔 開來來,在軟體架構上相當具有挑戰 • 平台專屬的 code 也要維持同⼀一個介⾯面,讓 Dart code 可 以呼叫,也就是,iOS/Android app 基本上要使⽤用同⼀一套 架構設計
  • 35. 團隊的組成 • 基本上要有夠資深的 iOS/Android ⼯工程師 • 搞定 codesign、發⾏行行上架等問題 • 要每個⼯工程師同時懂兩個平台很難 • 下⼀一步,就是這兩個⼯工程師應該還要有各⾃自的代理理,之後可以加⼊入 只寫 Dart 的⼈人 • 先以⼤大量量的單元測試加上 QA ⼿手動測試為主 • 因為 Flutter 的 Widget Test 實在很難寫,⽽而且有地⽅方還測不不到…
  • 36. 改變思維 • Flutter 的 Controller 不不是 iOS 的 Controller • iOS 的 Controller 是畫⾯面的基本單位 • Flutter 的 Widget ⾃自成天地,當外部想操作某個 Widget 時,才提供 ⼀一個 Controller 當做接⼝口 • Flutter 的 delegate 不不是 iOS 的 delegate • iOS 的 delegate 是集中處理理 callback 的物件,在 Flutter 中則使⽤用 builder function 或是 • Flutter 的 delegate 像是 Widget 的設定
  • 37. 改變思維 • 在 iOS 上,如果有個連線,我們可能會在 ViewController 中呼叫 NSURLSession 以及 NSURLSessionTask • 在 Flutter 中,我們的作法可能是把⽤用到這個連線的畫⾯面⽤用 FutureBuilder 包起來來 • <Furture><Widget>….</Future>
  • 38. 換台新電腦 • 你可能會同時開 • Android Studio • Xcode • Android Emulator • iOS Simulator • 其他編輯器器…
  • 40. Recap • 什什麼是 Flutter • 軟體⼯工程⽅方⾯面的雜談 • 發⾏行行 • 編譯 • 測試 • 團隊組成