Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SwiftUIと比較してみた時のFlutter
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Tatsuya Tanaka
June 23, 2020
Programming
2k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
SwiftUIと比較してみた時のFlutter
https://yj-meetup.connpass.com/event/178577/
#wwdctokyo
Tatsuya Tanaka
June 23, 2020
More Decks by Tatsuya Tanaka
See All by Tatsuya Tanaka
iPhoneのセンサー情報をmacOSアプリでリアルタイム活用するための技術
tattn
1
770
Better use of SwiftUI
tattn
0
500
Swift Concurrencyによる安全で快適な非同期処理
tattn
2
1.4k
iOSアプリの技術選択2022
tattn
7
4k
Widget Suggestions 対応と ヤフーの新OS対応
tattn
1
1.4k
WidgetKitで良い体験を作るには / Good experience with WidgetKit
tattn
2
1.9k
既存アプリにSwiftUIをどう組み込んでいくか
tattn
8
2.5k
iOS 14からのアプリ内課金
tattn
5
3.1k
iOS 14の位置情報系アップデート
tattn
0
22k
Other Decks in Programming
See All in Programming
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
2
720
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
180
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.4k
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
270
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
1
150
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.3k
エージェンティックRAGにAWSで入門しよう!
har1101
9
1.7k
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
170
dRuby over BLE
makicamel
2
390
さぁV100、メモリをお食べ・・・
nilpe
0
150
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
260
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.4k
Featured
See All Featured
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
300
The agentic SEO stack - context over prompts
schlessera
0
820
Typedesign – Prime Four
hannesfritz
42
3.1k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
330
Odyssey Design
rkendrick25
PRO
2
700
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
180
BBQ
matthewcrist
89
10k
Paper Plane
katiecoart
PRO
1
52k
Crafting Experiences
bethany
1
190
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
220
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
490
Transcript
SwiftUIͱൺֱͯ͠Έͨ࣌ͷFlutter ాதୡ (@tattn) #wwdctokyo
ాத ୡ / ͨͳͨͭ (@tattn) • Yahoo!ΧʔφϏ ←Yahoo!Ҋ • iOSΞϓϦΤϯδχΞ
• ৽ٕज़ͷݕূ @tattn @tanakasan2525 @tattn Copyright (C) 2020 Yahoo Japan Corporation. All Rights Reserved.
όʔνϟϧLODGEͲ͏Ͱ͠ΐ͏͔ʁ https://note.com/lodge/n/nfa4a40c057b1 3DϞσϥʔͱUnity͍͕͍Εҙ֎ͱ؆୯ʹ࡞Ε·͢ʂ
SwiftUIͬͯΈ·͔ͨ͠ʁ YES NO (clusterͷΤϞʔγϣϯ ͰԠ͍ͩ͘͞)
ࠓͷSwiftUI·ͩͭΒΈ͕ଟ͍ʂ
ݸਓతʹSwiftUIͰ࡞͍ͬͯͨΞϓϦΛ FlutterʹҠߦͨ͠Γɺ ۀͰFlutterΛݕূͨ͠Γ͍ͯ͠·͢
WWDC20લͱͷ͜ͱͰ Flutterͱൺֱͭͭ͠ SwiftUIͷਐԽʹظ͢ΔLTΛ͠·͢
Flutterͱ
Flutterͱ • GoogleʹΑͬͯ։ൃ͞ΕͨΦʔϓϯιʔεϞόΠϧΞϓϦSDK • ΫϩεϓϥοτϑΥʔϜ (iOS, Android, Web, macOS) •
DartͰهड़͢Δ • ίϯϙʔωϯτࢦɺϗοτϦϩʔυͳͲͷ ࠓͲ͖ͷઃܭػೳ
Flutterͷ͘͠Έ
Flutterͷ෦ https://flutter.dev/docs/resources/technical-overview ಠࣗͷϨϯμϦϯάΤϯδϯ(Skia) ͰUIViewʹඳը͠ɺUIΛදࣔ
ΈΜͳେ͖View Hierarchy FlutterViewControllerͷFlutterViewʹશͯඳը͞Ε͍ͯΔ (ScrollViewݟ͑ͳ͍ͱ͜Ζʹஔ) ͪͳΈʹ.xcworkspace࡞ΒΕΔͷͰ ωΠςΟϒͷσόοάXcodeͰͰ͖Δ
ίʔυ࣮ߦͷ͘͠Έ ϦϦʔεϏϧυ Dartίʔυ ػցޠ ίϯύΠϧ σόοάϏϧυ ػցޠ+Dart ࣮ߦதʹඞཁͳ෦͚ͩίϯύΠϧ͞ΕΔ (JIT) →ϗοτϦϩʔυ͕ޮ͘
࣮ߦલʹશͯίϯύΠϧ͞ΕΔ(AOT) →ಈ࡞͕͍
FlutterͰͷUIͷ࡞Γํ (ϘλϯΛԡͨ͠Β1૿͑ΔΞϓϦ)
ϘλϯΛԡ͢ͱ1૿͑Δը໘ (SwiftUI) struct ContentView: View { @State var count =
0 var body: some View { VStack { Text("Count: \(count)") .font(.largeTitle) Spacer() .frame(height: 20) Button(action: { self.count += 1 }, label: { Text("Increment") }) } } }
ϘλϯΛԡ͢ͱ1૿͑Δը໘ (Flutter) class CounterApp extends StatefulWidget { @override _CounterAppState createState()
=> _CounterAppState(); } class _CounterAppState extends State<CounterApp> { int _count = 0; @override Widget build(BuildContext context) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Count: $_count', style: Theme.of(context).textTheme.headline5), SizedBox(height: 20), FlatButton( child: Text('Increment'), onPressed: () => setState(() => _count++), ) ], ), ); } } ͪΐͬͱίʔυྔଟ͘ݟ͑·͕͢ɺ εχϖοτͰࣗಈੜ͞ΕΔͷͰهड़ྔಉ͘͡Β͍
ϘλϯΛԡ͢ͱ1૿͑Δը໘ (Flutter) class _CounterAppState extends State<CounterApp> { int _count =
0; @override Widget build(BuildContext context) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Count: $_count', style: Theme.of(context).textTheme.headline5), SizedBox(height: 20), FlatButton( child: Text('Increment'), onPressed: () => setState(() => _count++), ) ], ), ); } } ࣗಈੜ෦ΛΧοτͯ͠ຊ࣭ͷΈʹ͢Δͱ͜Μͳײ͡
ϘλϯΛԡ͢ͱ1૿͑Δը໘ (Flutter | SwiftUI) ࣅͨΑ͏ͳײ֮Ͱॻ͚·͢ class _CounterAppState extends State<CounterApp> {
int _count = 0; @override Widget build(BuildContext context) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Count: $_count', ɹɹ style: Theme.of(context).textTheme.headline5), SizedBox(height: 20), FlatButton( child: Text('Increment'), onPressed: () => setState(() => _count++), ) ], ), ); } } struct ContentView: View { @State var count = 0 var body: some View { VStack { Text("Count: \(count)") .font(.largeTitle) Spacer() .frame(height: 20) Button(action: { self.count += 1 }, label: { Text("Increment") }) } } }
Flutterͷྑ͍ͱ͜Ζ (vs SwiftUI)
Hot Reload͕ "ͪΌΜͱ" ͑Δ • ⌘+SΛԡ͢ͱอଘ͞ΕࣗಈͰView͕ߋ৽͞ΕΔ • γϛϡϨʔλͰ࣮ػͰ͑Δ • ϓϩδΣΫτ͕େ͖ͯ͘ө·Ͱ1ඵ͘Β͍
• Ϧϩʔυલͷঢ়ଶ͕Δ
Hot Reload͕ "ͪΌΜͱ" ͑Δ • ⌘+SΛԡ͢ͱอଘ͞ΕࣗಈͰView͕ߋ৽͞ΕΔ • γϛϡϨʔλͰ࣮ػͰ͑Δ • ϓϩδΣΫτ͕େ͖ͯ͘ө·Ͱ1ඵ͘Β͍
• Ϧϩʔυલͷঢ়ଶ͕Δ SwiftUIͷϓϨϏϡʔίϯϙʔωϯτ୯Ґ͕جຊͰ͕͢ɺ FlutterσόοάϏϧυதͷΞϓϦΛಈతʹॻ͖͑Δײ֮
SwiftUIΑΓॊೈ • ϨΠΞτͰ࣮ݱͰ͖ͳ͍έʔε΄΅ͳͦ͞͏ • Γͳ͍ػೳΛิ͏খ͞ͳϥΠϒϥϦ͕ଟ͍ • ։ൃαΠΫϧ͕ૣ͘ɺ͙͢ʹΔ
SwiftUIΑΓॊೈ • ϨΠΞτͰ࣮ݱͰ͖ͳ͍έʔε΄΅ͳͦ͞͏ • Γͳ͍ػೳΛิ͏খ͞ͳϥΠϒϥϦ͕ଟ͍ • ։ൃαΠΫϧ͕ૣ͘ɺ͙͢ʹΔ • FlutterͷϑϨʔϜϫʔΫଆDart෦ ΞϓϦͷσόοά࣌ʹϒϨʔΫϙΠϯτΛஔ͍ͯ
σόοάͰ͖ΔʂͷͰमਖ਼ͷෑډ͕͍ (ͤΔਓ͕ଟ͍)
AndroidͰಈ͘ʂʂʂ
ωΠςΟϒͷػೳͲ͏͢Δͷʁ
ωΠςΟϒػೳͷݺͼग़͠ํ PlatformView PlatformChannel UIViewΛͬͯiOSͷΈͰUIΛಈ͔͠ɺ දࣔ݁ՌΛSkiaʹૹͬͯϨϯμϦϯά͢Δɻ →ωΠςΟϒͷViewΛFlutterͷWidgetʹΈࠐΊΔ ωΠςΟϒͰػೳΛ࣮͠ɺDart͔Βݺͼग़͢Έɻ ૬ޓʹσʔλͷΓऔΓ͕Ͱ͖Δ (σʔλܕͷ੍ݶ͋Δ) ͲͪΒSwift
/Kotlin Ͱॻ͚Δʂ
ωΠςΟϒΞϓϦʹFlutterΛຒΊࠐΉํ๏͋Δ Add to App ɾCocoaPodsͰFlutterΞϓϦΛऔΓࠐΉ ɾίϚϯυͰFrameworkԽͯ͠औΓࠐΉ ɾpodspecͰFrameworkԽΛCocoaPodsʹ·͔ͤͯऔΓࠐΉ IUUQTqVUUFSEFWEPDTEFWFMPQNFOUBEEUPBQQ ͳͲͷํ๏ͰطଘͷωΠςΟϒΞϓϦʹ FlutterΛ෦ಋೖ͢Δ͜ͱͰ͖·͢ɻ
(FlutterͷUI1ຕͷViewControllerͱͯ͠औΓѻ͑Δ)
SwiftUIͷํ͕ྑ͍෦
SwiftUIͷྑ͍ͱ͜Ζ ϝιουνΣʔϯ (modifier) ʹΑΔViewͷΧελϚΠζ ೖΕࢠΛݮΒͤͯಡΈ͍͢ɻ (ͨΓલͰ͕͢)ωΠςΟϒͷػೳΛ͔ΜͨΜʹσόοάͰ͖Δɻ Swiftຊʹྑ͍ݴޠɻ Text("WWDC") .padding() .border(Color.red,
width: 3) Container( decoration: BoxDecoration( border: Border.all(color: Colors.red, width: 3), ), padding: const EdgeInsets.all(8), child: Text("WWDC"), ) Container( decoration: BoxDecoration( border: Border.all(color: Colors.red, width: 3), ), child: Padding( padding: const EdgeInsets.all(8), child: Text("WWDC"), ), ), ωετΛݮΒͨ͢ΊʹpaddingΛ ҾͰࢦఆͰ͖ΔWidget͋Δ
͜Ε͔Β࢝·ΔWWDCʹ ظ͢Δ͜ͱ
Apple͞Μ͓ئ͍͠·͢ʂ ɾHot ReloadͷਐԽʹظʂ ɹɹɾσόοάϏϧυͰಈ͔ͯ͠ΔΞϓϦΛ ɹɹɹঢ়ଶΛͭͭ͠ॻ͖͍͑ͨ ɾViewͷΧελϚΠζੑΛߴͯ͘͠΄͍͠ʂ ɹɹɾཪʹ͍ΔUIKitAppKitͷViewʹ৮ΕΔΈͰྑ͍Ͱ͢ ɾWebͰಈ͘Α͏ʹͯ͠΄͍͠ʂ(ຊAndroidαϙʔτͯ͠΄͍͚͠Ͳ᩵ݴ͍·ͤΜ) ɹɹɾHTML /
CSS / JSΛexport͢Δػೳཉ͍͠ IUUQTqVUUFSEFWEPDTEFWFMPQNFOUUPPMTEFWUPPMTJOTQFDUPS
·ͱΊ
·ͱΊ • Flutter͔ͳΓΑ͘Ͱ͖͍ͯͯɺ࣮༻తɻ • ݱঢ়ͰSwiftUI/UIKitΑΓ"ѹత"ʹ շదʹॻ͚Δɻ • ͰSwiftࣗମSwiftUIͷઃܭັྗతʂ • ͜Ε͔Β࢝·ΔWWDCͰͷSwiftUIͷਐԽʹظ