Slide 1

Slide 1 text

SwiftUIͱൺֱͯ͠Έͨ࣌ͷFlutter ాதୡ໵ (@tattn) #wwdctokyo

Slide 2

Slide 2 text

ాத ୡ໵ / ͨͳͨͭ (@tattn) • Yahoo!ΧʔφϏ ←Yahoo!৐׵Ҋ಺ • iOSΞϓϦΤϯδχΞ • ৽ٕज़ͷݕূ @tattn @tanakasan2525 @tattn Copyright (C) 2020 Yahoo Japan Corporation. All Rights Reserved.

Slide 3

Slide 3 text

όʔνϟϧLODGEͲ͏Ͱ͠ΐ͏͔ʁ https://note.com/lodge/n/nfa4a40c057b1 3DϞσϥʔͱUnity࢖͍͕͍Ε͹ҙ֎ͱ؆୯ʹ࡞Ε·͢ʂ

Slide 4

Slide 4 text

SwiftUI࢖ͬͯΈ·͔ͨ͠ʁ YES NO (clusterͷΤϞʔγϣϯ Ͱ൓Ԡ͍ͩ͘͞)

Slide 5

Slide 5 text

ࠓͷSwiftUI͸·ͩͭΒΈ͕ଟ͍ʂ

Slide 6

Slide 6 text

ݸਓతʹSwiftUIͰ࡞͍ͬͯͨΞϓϦΛ FlutterʹҠߦͨ͠Γɺ ۀ຿Ͱ΋FlutterΛݕূͨ͠Γ͍ͯ͠·͢

Slide 7

Slide 7 text

WWDC20௚લͱͷ͜ͱͰ Flutterͱൺֱͭͭ͠ SwiftUIͷਐԽʹظ଴͢ΔLTΛ͠·͢

Slide 8

Slide 8 text

Flutterͱ͸

Slide 9

Slide 9 text

Flutterͱ͸ • GoogleʹΑͬͯ։ൃ͞ΕͨΦʔϓϯιʔεϞόΠϧΞϓϦSDK • ΫϩεϓϥοτϑΥʔϜ (iOS, Android, Web, macOS) • DartͰهड़͢Δ • ίϯϙʔωϯτࢦ޲ɺϗοτϦϩʔυͳͲͷ ࠓͲ͖ͷઃܭ΍ػೳ

Slide 10

Slide 10 text

Flutterͷ͘͠Έ

Slide 11

Slide 11 text

Flutterͷ಺෦ https://flutter.dev/docs/resources/technical-overview ಠࣗͷϨϯμϦϯάΤϯδϯ(Skia) ͰUIViewʹඳը͠ɺUIΛදࣔ

Slide 12

Slide 12 text

ΈΜͳେ޷͖View Hierarchy FlutterViewController಺ͷFlutterViewʹશͯඳը͞Ε͍ͯΔ (ScrollView͸ݟ͑ͳ͍ͱ͜Ζʹ഑ஔ) ͪͳΈʹ.xcworkspace΋࡞ΒΕΔͷͰ ωΠςΟϒͷσόοά͸XcodeͰͰ͖Δ

Slide 13

Slide 13 text

ίʔυ࣮ߦͷ͘͠Έ ϦϦʔεϏϧυ Dartίʔυ ػցޠ ίϯύΠϧ σόοάϏϧυ ػցޠ+Dart ࣮ߦதʹඞཁͳ෦෼͚ͩίϯύΠϧ͞ΕΔ (JIT) →ϗοτϦϩʔυ͕ޮ͘ ࣮ߦલʹશͯίϯύΠϧ͞ΕΔ(AOT) →ಈ࡞͕଎͍

Slide 14

Slide 14 text

FlutterͰͷUIͷ࡞Γํ (ϘλϯΛԡͨ͠Β1૿͑ΔΞϓϦ)

Slide 15

Slide 15 text

ϘλϯΛԡ͢ͱ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") }) } } }

Slide 16

Slide 16 text

ϘλϯΛԡ͢ͱ1૿͑Δը໘ (Flutter) class CounterApp extends StatefulWidget { @override _CounterAppState createState() => _CounterAppState(); } class _CounterAppState extends State { 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++), ) ], ), ); } } ͪΐͬͱίʔυྔଟ͘ݟ͑·͕͢ɺ εχϖοτͰࣗಈੜ੒͞ΕΔͷͰهड़ྔ͸ಉ͘͡Β͍

Slide 17

Slide 17 text

ϘλϯΛԡ͢ͱ1૿͑Δը໘ (Flutter) class _CounterAppState extends State { 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++), ) ], ), ); } } ࣗಈੜ੒෦෼ΛΧοτͯ͠ຊ࣭ͷΈʹ͢Δͱ͜Μͳײ͡

Slide 18

Slide 18 text

ϘλϯΛԡ͢ͱ1૿͑Δը໘ (Flutter | SwiftUI) ࣅͨΑ͏ͳײ֮Ͱॻ͚·͢ class _CounterAppState extends State { 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") }) } } }

Slide 19

Slide 19 text

Flutterͷྑ͍ͱ͜Ζ (vs SwiftUI)

Slide 20

Slide 20 text

Hot Reload͕ "ͪΌΜͱ" ࢖͑Δ • ⌘+SΛԡ͢ͱอଘ͞ΕࣗಈͰView͕ߋ৽͞ΕΔ • γϛϡϨʔλͰ΋࣮ػͰ΋࢖͑Δ • ϓϩδΣΫτ͕େ͖ͯ͘΋൓ө·Ͱ1ඵ͘Β͍ • Ϧϩʔυલͷঢ়ଶ͕࢒Δ

Slide 21

Slide 21 text

Hot Reload͕ "ͪΌΜͱ" ࢖͑Δ • ⌘+SΛԡ͢ͱอଘ͞ΕࣗಈͰView͕ߋ৽͞ΕΔ • γϛϡϨʔλͰ΋࣮ػͰ΋࢖͑Δ • ϓϩδΣΫτ͕େ͖ͯ͘΋൓ө·Ͱ1ඵ͘Β͍ • Ϧϩʔυલͷঢ়ଶ͕࢒Δ SwiftUIͷϓϨϏϡʔ͸ίϯϙʔωϯτ୯Ґ͕جຊͰ͕͢ɺ Flutter͸σόοάϏϧυதͷΞϓϦΛಈతʹॻ͖׵͑Δײ֮

Slide 22

Slide 22 text

SwiftUIΑΓॊೈ • ϨΠΞ΢τͰ࣮ݱͰ͖ͳ͍έʔε͸΄΅ͳͦ͞͏ • ଍Γͳ͍ػೳΛิ͏খ͞ͳϥΠϒϥϦ͕ଟ͍ • ։ൃαΠΫϧ͕ૣ͘ɺ͙͢ʹ௚Δ

Slide 23

Slide 23 text

SwiftUIΑΓॊೈ • ϨΠΞ΢τͰ࣮ݱͰ͖ͳ͍έʔε͸΄΅ͳͦ͞͏ • ଍Γͳ͍ػೳΛิ͏খ͞ͳϥΠϒϥϦ͕ଟ͍ • ։ൃαΠΫϧ͕ૣ͘ɺ͙͢ʹ௚Δ • FlutterͷϑϨʔϜϫʔΫଆ΋Dart෦෼͸ ΞϓϦͷσόοά࣌ʹϒϨʔΫϙΠϯτΛஔ͍ͯ σόοάͰ͖ΔʂͷͰमਖ਼ͷෑډ͕௿͍ (௚ͤΔਓ͕ଟ͍)

Slide 24

Slide 24 text

AndroidͰ΋ಈ͘ʂʂʂ

Slide 25

Slide 25 text

ωΠςΟϒͷػೳ͸Ͳ͏͢Δͷʁ

Slide 26

Slide 26 text

ωΠςΟϒػೳͷݺͼग़͠ํ PlatformView PlatformChannel UIViewΛ࢖ͬͯiOSͷ࢓૊ΈͰUIΛಈ͔͠ɺ දࣔ݁ՌΛSkiaʹૹͬͯϨϯμϦϯά͢Δɻ →ωΠςΟϒͷViewΛFlutterͷWidget಺ʹ૊ΈࠐΊΔ ωΠςΟϒͰػೳΛ࣮૷͠ɺDart͔Βݺͼग़͢࢓૊Έɻ ૬ޓʹσʔλͷ΍ΓऔΓ͕Ͱ͖Δ (σʔλܕͷ੍ݶ͸͋Δ) ͲͪΒ΋Swift /Kotlin Ͱॻ͚Δʂ

Slide 27

Slide 27 text

ωΠςΟϒΞϓϦʹFlutterΛຒΊࠐΉํ๏΋͋Δ Add to App ɾCocoaPodsͰFlutterΞϓϦΛऔΓࠐΉ ɾίϚϯυͰFrameworkԽͯ͠औΓࠐΉ ɾpodspecͰFrameworkԽΛCocoaPodsʹ·͔ͤͯऔΓࠐΉ IUUQTqVUUFSEFWEPDTEFWFMPQNFOUBEEUPBQQ ͳͲͷํ๏ͰطଘͷωΠςΟϒΞϓϦʹ FlutterΛ෦෼ಋೖ͢Δ͜ͱ΋Ͱ͖·͢ɻ (FlutterͷUI͸1ຕͷViewControllerͱͯ͠औΓѻ͑Δ)

Slide 28

Slide 28 text

SwiftUIͷํ͕ྑ͍෦෼

Slide 29

Slide 29 text

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΋͋Δ

Slide 30

Slide 30 text

͜Ε͔Β࢝·ΔWWDCʹ ظ଴͢Δ͜ͱ

Slide 31

Slide 31 text

Apple͞Μ͓ئ͍͠·͢ʂ ɾHot ReloadͷਐԽʹظ଴ʂ ɹɹɾσόοάϏϧυͰಈ͔ͯ͠ΔΞϓϦΛ ɹɹɹঢ়ଶΛ࢒ͭͭ͠ॻ͖׵͍͑ͨ ɾViewͷΧελϚΠζੑΛߴͯ͘͠΄͍͠ʂ ɹɹɾཪʹ͍ΔUIKit΍AppKitͷViewʹ৮ΕΔ࢓૊ΈͰ΋ྑ͍Ͱ͢ ɾWebͰಈ͘Α͏ʹͯ͠΄͍͠ʂ(ຊ౰͸Androidαϙʔτͯ͠΄͍͚͠Ͳ᩵୔͸ݴ͍·ͤΜ) ɹɹɾHTML / CSS / JSΛexport͢Δػೳཉ͍͠ IUUQTqVUUFSEFWEPDTEFWFMPQNFOUUPPMTEFWUPPMTJOTQFDUPS

Slide 32

Slide 32 text

·ͱΊ

Slide 33

Slide 33 text

·ͱΊ • Flutter͸͔ͳΓΑ͘Ͱ͖͍ͯͯɺ࣮༻తɻ • ݱঢ়Ͱ͸SwiftUI/UIKitΑΓ΋"ѹ౗త"ʹ շదʹॻ͚Δɻ • Ͱ΋Swiftࣗମ΍SwiftUIͷઃܭ͸ັྗతʂ • ͜Ε͔Β࢝·ΔWWDCͰͷSwiftUIͷਐԽʹظ଴