Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
SwiftUIと比較してみた時のFlutter
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Tatsuya Tanaka
June 23, 2020
Programming
2.1k
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
800
Better use of SwiftUI
tattn
0
520
Swift Concurrencyによる安全で快適な非同期処理
tattn
2
1.5k
iOSアプリの技術選択2022
tattn
7
4k
Widget Suggestions 対応と ヤフーの新OS対応
tattn
1
1.4k
WidgetKitで良い体験を作るには / Good experience with WidgetKit
tattn
2
2k
既存アプリにSwiftUIをどう組み込んでいくか
tattn
8
2.6k
iOS 14からのアプリ内課金
tattn
5
3.2k
iOS 14の位置情報系アップデート
tattn
0
23k
Other Decks in Programming
See All in Programming
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
310
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
270
setup-vp GitLab対応の裏側
naokihaba
0
150
AWSに止められる覚悟してますか?
morizo_1984
2
510
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
530
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
190
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
580
カツオ、ご期待ください
suneo3476
0
150
FreeBSDでZabbixを動かす
kenkino
0
360
Security issues being discussed on Web Platforms
petamoriken
0
1.4k
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
450
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
14
6.7k
Featured
See All Featured
The World Runs on Bad Software
bkeepers
PRO
72
12k
Making Projects Easy
brettharned
120
6.8k
Automating Front-end Workflow
addyosmani
1369
210k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
260
It's Worth the Effort
3n
188
29k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
270
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
450
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
350
Why Our Code Smells
bkeepers
PRO
340
58k
Un-Boring Meetings
codingconduct
0
440
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
Designing Powerful Visuals for Engaging Learning
tmiket
1
590
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ͷਐԽʹظ