Mais conteúdo relacionado Semelhante a 給 iOS 工程師的 Flutter 開發 (20) Mais de Weizhong Yang (18) 給 iOS 工程師的 Flutter 開發2. Flutter
• https://flutter.io
• ⼀一個寄宿在⽬目前 iOS、Android 平台上的新平台
• 是設計給 Google 未來來作業系統 Fuchsia 的應⽤用程式開發層
• Dart VM + Skia Render 引擎
• 在 iOS/Android App 中包入 Flutter Framework 後,執⾏行行 Dart
code,同⼀一個 App 在不同平台可以 render 出相同的效果
• 可以與 ObjC/Swift/Java/Kotlin 橋接
• 重新發明 Flash?
3. ⽤用 Flutter 可能有什什麼好處?
• 以⽬目前的執⾏行行效能與完成度來來看,似乎不能不管
• 如果同時需要開發 iOS/Android,可以⼤大量量共⽤用程式碼
• iOS/Android 上可以 Render 出⼀一樣的畫⾯面,設計師可以只
需要做⼀一套設計
• 現在就先投資未來來的 Google 作業系統,以及 Flutter 還可
能移植到 Windows/Mac/瀏覽器執⾏行行的可能
4. ⽤用 Flutter 會犧牲什什麼
• 還不⽀支援⼀一些 iPhone 的特殊功能,如 3D Touch
• 不過你的 App 本來來也就沒在⽀支援 3D Touch
• 犧牲跟 macOS/tvOS/watchOS 共⽤用程式碼的機會
• 不過你本來來也沒在⽀支援
• 好的 Dart 語⾔言的⼯工程師不好找
• 不過反正你本來來也找不到好的 ObjC/Swift/Java/Kotlin ⼯工
程師
5. ⽤用 Flutter 會犧牲什什麼
• 在 iOS 上由於⽤用的不是 UIKit 元件,看起來來會比較像
Google Photo 的感覺,⽽而不像「很 Apple」的 App
• 無法使⽤用 XCTest 測試
• 上線後,從 iOS 的 crash log 中看不出 Dart 程式的問題
• 專案會與 Firebase 變得更更緊密,因為現在供 Flutter 使⽤用的
BaaS、Analytics…都只有 Firebase 這個選擇
6. 使⽤用 Flutter 的挑戰
• Flutter 無法使⽤用⼀一些平台專屬功能,⽽而可能需要寫與該平
台橋接的程式,所以現階段還是得懂⼀一定的 iOS/Android
開發
• 哪些部分⽤用 Flutter 寫,哪些寫在 iOS/Android 橋接端,非
常挑戰 App 架構的能⼒力力
7. 安裝
• 先裝好 Xcode 以及 Android Studio
• 去 https://flutter.io/setup-macos/ 下載 zip 檔解壓
• 執⾏行行 flutter doctor 看看少了了什什麼
• ⽤用 homebrew 裝 ideviceinstaller 以及 ios-deploy
• IDE 可⽤用 Android Studio 或 VSCode
10. Dart 程式語⾔言
• 這年年頭的 OO 語⾔言其實都差不多,但還是有少部分差異異
• Dart 除了了可以在 Flutter 執⾏行行以外,也可以編譯成 JS 在網
⾴頁使⽤用,也可以單獨在 Dart VM 執⾏行行
• 所以 Dart 可以寫單獨的 CLI 程式,在 server side 執⾏行行
• Dart 在網⾴頁上可以搭配 Angular 使⽤用…不過這年年頭好像寫
Angular 的⼈人比較少
11. 單獨安裝 Dart
• ⽤用 homebrew 安裝 dart
• brew install dart
• 同時建議安裝 stagehand,Dart 的新專案產⽣生器
• pub global activate stagehand
12. 開始新專案
Swift Package Manager
$swift package init
init 後可接 --type
empty|library|executable|
system-module
Dart
$stagehand [project type]
Project type 可接
• console-full
• package-simple
• server-shelf
• web-angular…
13. Dependency
iOS/Swift 開發
• 可使⽤用 SPM package 或是
Cocoapods
• Cocoapods 可在 https://
cocoapods.org/ 查詢
• SPM Package 的
Dependency 設定寫在
Package.swift 中
• 使⽤用 swift package update
更更新
Dart
• 使⽤用 pub
• 可在 https://
pub.dartlang.org/ 查詢
• Dependency 設定寫在
pubspec.yaml 中
• ⽤用 pub get 指令更更新
15. Class
Swift
class Sample {
var x:Int
init (x: Int) {
self.x = x
}
func someMethod() {
self.hi()
}
}
var sample = Sample(x: 1)
Dart
class Sample {
int x = 0;
Sample(this.x) {
}
someMethod() {
this.hi();
}
}
Sample sample = new
Sample(1);
17. 匿名函式
Swift
{ x in …
}
或
{ $0.doSomething() }
Dart
(int x) {
…
}
或寫成單⾏行行
(x) => doSomething(x);
18. 匿名函式
Swift
class MyClass {
var f: ((Int)->Int)?
}
var x = MyClass()
x.f = { $0 + 1 }
print("(x.f!(2))"
// Swift 也可以⽤用 typealias
Dart
// ⼀一定要⽤用 typedef
typedef int Call(int);
class MyClass {
Call f;
}
main() {
var x = new MyClass();
x.f = (i) => i + 1;
print(x.f(2));
}
21. Delegate?
• 在 ObjC/Swift 中⼤大量量使⽤用 Delegate Pattern
• 在 Dart 中改⽤用 Stream Controller
• Stream Controller 可以⽤用來來發送事件,Listener 則監聽從
Stream Controller 發送的事件
22. Stream Controller in Dart
import 'dart:async';
class MyClass {
StreamController controller = new StreamController.broadcast();
Stream get didSomething = controller.stream;
someMethod() {
this.controller.add(‘Test’);
}
}
MyClass obj = new MyClass();
obj.didSomething.listen( (String s) {
print(s);
});
23. Dart 也有叫做 Delegate 的東⻄西
• 不是每個叫做 Delegate 的東⻄西都是同樣意思
• ObjC/Swift 的 Delegate 通常⽤用在 Model 或 View 發⽣生改變
的時候,⽤用來來通知 Controller,也就是 Controller 是 Model
或 View 的 Delegate
• Dart 上也可以實作 ObjC/Swift 的 delegate,⽤用 abstract 代
替 protocol…但好像沒有⼈人這麼做
24. Dart 也有叫做 Delegate 的東⻄西
• Dart 的 Delegate 則指的是某個物件要使⽤用的規則,比較是
⼀一種純 Model 物件
• Dart 的 Delegate 很像 CocoaTouch 中 UICollectionView
與 UICollectionViewLayout 的關係
• 像是 Flutter 的 GirdView 的 delegate,就是 Grid 有幾⾏行行、
間距多少…等邏輯
25. Notification Center?
• 有類似的東⻄西 https://github.com/stevenroose/dart-events
• 另外也有⼈人在 Flutter 上實作 redux https://
pub.dartlang.org/packages/flutter_redux
28. Widget Model/Builder
• iOS 上畫⾯面主要由 View Controller/View 組成,View Controller
管理理⼀一個 view property,然後在上⾯面新增/移除 subview
• Flutter 的畫⾯面是由 Widget 組成,每個 Widget ⼜又都是⼀一個
builder,build 出這個 Widget 下有哪些內部的 Widget
• …其實 Flutter 裡頭什什麼都是 Widget
• Build 出的 Widget 再交給 Flutter 的 Renderer 給 render 成畫⾯面
• 某⽅方⾯面來來看,Flutter 的架構中比較沒有明確的 MVC 之分,⼀一個
Widget 像是扮演了了 Controller 與 View 的⾓角⾊色,但本質上
Widget 卻⼜又是 Model…
29. Widget Model/Builder
• Widget 在 Build 出底下的 Widget 之後,就無法再改動,
要改變畫⾯面,就要再 Build ⼀一次,Build 出另外⼀一份 Widget
• ⼀一個 widget 有點像是 Web 開發的 Virtual DOM,但比較不
同的時,Flutter 的 widget model 沒有做 HTML Tag/CSS
分離,⽽而是 widget 本⾝身就帶有樣式的性質
• Widget 做的事情也超過 DOM Element,Layout/動畫/
30. 對比 iOS 開發看 Widget
• iOS 上,每個 view 的重繪,是在對 UIView 呼叫
setNeedDisplay 之後,才會呼叫 UIView 的 drawRect: 或
是 CALayer 的 drawInContext: 重繪
• 更更新⼀一個 widget 似乎有點類似:對 Widget 的 State 呼叫
setState() 後,才會重新 build 出⼀一份 widget ,由這份
widget render 出新的畫⾯面
• 也有點像是在 Vue.js 裡頭對某個 component 呼叫
$nextTick()
31. Widget 有兩兩種
• Stateless Widget:Widget build 出來來之後就不會改變內部
widget,往往⽤用在最⼤大或最⼩小的元件。最⼤大如整個 App 的
框架(MaterialApp Class)最⼩小的元件如⽂文字框(Text
Class)
• Stateful Widget:會改變狀狀態的 widget,負責掌管⼀一個
State 屬性,在 State 中再負責 build 出 widget。⼤大多時間
我們會寫這類的 Widget。
32. App:第⼀一個 Widget
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: ‘My App',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new HomePage(title: ‘Home Page’),
);
}
} // 然後我們就可以繼續寫 HomePage class
34. Decorator 風格
• 在其他框架中的元件屬性,在 Flutter 中則往往設計成被另
外⼀一個 Widget 包裝起來來
• ⼀一堆⽂文字置中: Center -> Column -> [Text, Text]
• 圖形放在圓框裡:Box Decoration -> Image
42. 什什麼時候去呼叫 Web API?
• 可以使⽤用 Future Block
• 或是在 initState 的時候,呼叫 Web API call,在 Promise
結束的時候呼叫 setState() 更更新畫⾯面
• 如果要做⾴頁⾯面 retry 的話,後⾯面這種作法可能比較好
44. Scaffold
• ⼀一個 App 最常⽤用的框架
• AppBar -> 類似 iOS NavigationBar
• Drawer -> 漢堡選單
• Floating Action Button -> Material Design 的特殊 UI
• Bottom Navigation Bar -> 類似 iOS 的 TabBar
46. ⼀一些眉眉⾓角⾓角
• ListView 與 Grid View 只能單個 Section,如果想要多
Section 的 ListView 或 GridView,要改⽤用
CustomScrollView
• CustomScrollView 的 children 得要⽤用 SliverListView 以及
SliverGridView,⽽而不是直接把 ListView 或 GridView 放進
去
49. Open URL
• 在 iOS 上可以呼叫 UIApplication 的 openURL: 以及
canOpenURL:
• Flutter 上要安裝 url_launcher https://pub.dartlang.org/
packages/url_launcher
• 改寫 pubspec.yaml 然後⽤用 flutter packages get 更更新
dependencies
50. 學習資源
• Flutter 原廠⽂文件 https://flutter.io/docs/
• Coding with Flutter https://medium.com/coding-with-
flutter
• Google IO 2018 其實沒講什什麼東⻄西