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を書くために / After Party iOSDC Japan 202...
Search
Atsuya Sato
October 01, 2021
Technology
1.2k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
チームでSwiftUIを書くために / After Party iOSDC Japan 2021 SwiftUI
2021/10/1に開催されたAfter Party iOSDC Japan 2021の登壇資料です
Atsuya Sato
October 01, 2021
More Decks by Atsuya Sato
See All by Atsuya Sato
アプリ内にテーマ機能を実装する / pixiv-app-talk-202604-theme-feature
natmark
0
55
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
2
670
iOS 17で追加されたSubscriptionStoreView を利用して5分でサブスク実装チャレンジ
natmark
0
1.5k
Pastelaのアプリ内課金開発の裏側 / pixiv-app-night-202502-pastela-iap
natmark
2
210
詳解UIWindow
natmark
3
5.6k
画面最前面に表示されるデバッグツールを作る
natmark
2
350
最低サポートOSバージョンをあげた時のストア表示について / potatotips81-store-page-apperance-with-deployment-target-updated
natmark
2
800
施策基盤としてのディープリンク〜なめらかにアプリが開く体験のために〜
natmark
9
9.1k
iOSDC_SwiftUI_Text
natmark
4
5.9k
Other Decks in Technology
See All in Technology
internal/testlog で遊ぼう
rokuosan
0
400
AI駆動開発をチームに根付かせる - 「1行も書かない」チームがHarnessを育てた1年 -
kenichirokimura
6
3.4k
全社に広がるMCPサーバーを、 どう安全に管理するか MCPass開発の舞台裏
mtpooh
3
200
指示待ちから変化に応じるClaude Codeへ!~環境からAgentへの帰り道を作る~
gotalab555
8
1.6k
AI時代の「OAuth認証」にどう物申すか?(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
370
IHV like なユースケースへのOpenID Connect 関連仕様の適用事例
optim
0
380
Microsoft MVP プログラムを紹介するから目指す人増えてくれ
tsubakimoto_s
0
150
顧客の要望は2次情報である 〜アンテナを張るFDEの構造論〜
noriakioji
5
1.1k
エージェント化するAI:現在地とその先に起きる変化 / AI as Agents: The Current State and the Changes Ahead
ks91
PRO
0
170
Bill One 開発エンジニア 紹介資料
sansan33
PRO
7
20k
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.3k
When Token Pruning is Worse than Random: Understanding Visual Token Information in VLLMs
sansantech
PRO
0
170
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Building AI with AI
inesmontani
PRO
1
1.2k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
260
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
A better future with KSS
kneath
240
18k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Thoughts on Productivity
jonyablonski
76
5.3k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
480
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
670
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
400
WENDY [Excerpt]
tessaabrams
12
39k
Transcript
νʔϜͰSwiftUIΛॻͨ͘Ίʹ ~ಡΈ͘͢อक͍͢͠SwiftUIͷઃܭʹ͍ͭͯߟ͑ͨ͜ͱ~ After Party iOSDC Japan 2021 / Atsuya Sato
ࠤ౻ ರ (͋ͭ) @n_atmark • iOS / Android ΤϯδχΞ •
ݱࡏΫοΫύουAndroidΞϓϦͷʮ͔͍ͷʯλϒΛӶҙ։ൃத 2019/04 2021/01 • ΫοΫύου৽ଔೖࣾ • ങࣄۀຊ෦ ങϓϩμΫτ։ൃ෦ • ΫοΫύουϚʔτͷྲྀ௨͚ͷαʔϏε։ൃɺϋʔυΣΞ։ൃͳͲʹैࣄ • ΫοΫύουࣄۀຊ෦ ങαʔϏε։ൃ෦ • ΫοΫύουiOSΞϓϦͷʮ͔͍ͷʯλϒͷ։ൃʹैࣄ
ΞδΣϯμ • എܠ • ։ൃ͍ͯ͠ΔϓϩμΫτͷհ • νʔϜϓϩμΫτͷنײ • SwiftUIΛ༻͍ͯ1ؒ։ൃͯ͠Έͯ •
ಡΈͯ͘͢อक͍͢͠ઃܭʹ͍ͭͯߟ͑ͨࣄ • ౷Ұͨ͠ॻ͖ํͰϨΠΞτΛઃܭ͢ΔͨΊʹ • ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ • ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ • ·ͱΊ
։ൃ͍ͯ͠ΔϓϩμΫτͷհ • എܠ • ։ൃ͍ͯ͠ΔϓϩμΫτͷհ • νʔϜϓϩμΫτͷنײ • SwiftUIΛ༻͍ͯ1ؒ։ൃͯ͠Έͯ
ΫοΫύουΞϓϦʮങ͍ػೳʯͷհ
ΫοΫύουΞϓϦʮങ͍ػೳʯͷհ
ΫοΫύουΞϓϦʮങ͍ػೳʯͷհ ৯ࡐ͔ΒϨγϐ͕୳ͤΔ ৯ࡐΛങͬͨਓ͕ ࣮ࡍʹ࡞ͬͨྉཧ ΛࢀߟʹͰ͖Δ
ΫοΫύουΞϓϦʮങ͍ػೳʯͷհ レシピから必要な⾷材 を購⼊できる
νʔϜϓϩμΫτͷنײ • എܠ • ։ൃ͍ͯ͠ΔϓϩμΫτͷհ • νʔϜϓϩμΫτͷنײ • SwiftUIΛ༻͍ͯ1ؒ։ൃͯ͠Έͯ
νʔϜͱ։ൃ͍ͯ͠ΔϓϩμΫτʹ͍ͭͯ • ങαʔϏε։ൃ෦ • ʮϨγϐʯ×ʮങ͍ʯʹΑͬͯ৽ͨͳՁΛੜΈ ग़͢ઓ • ΫοΫύουiOSΞϓϦͷʮങ͍ػೳʯ • ΤϯδχΞ6ਓ
(iOS 3ɺαʔόʔαΠυ3) • + ඇఆظͰΠϯλʔϯੜ͕νʔϜʹδϣΠϯ
ΫοΫύουΞϓϦʮങ͍ػೳʯͷ։ൃ • ϚϧνϞδϡʔϧԽ͞Ε͍ͯΔΫοΫύουΞϓϦͷ Feature ModuleͷҰͭͱͯ͠ػೳ։ൃ (KaimonoϞδϡʔϧ)
https://speakerdeck.com/giginet/da-gui-mo-naapurifalsemarutimoziyurugou-cheng-falseshi-jian ⼤規模なアプリのマルチモジュール構成の実践
ΫοΫύουΞϓϦʮങ͍ػೳʯͷ։ൃ • ΄΅શͯSwiftUIͰ։ൃத • VIPERΞʔΩςΫνϟͷ͏ͪɺView෦ͷΈͰ SwiftUIΛར༻͢Δઃܭ
https://techlife.cookpad.com/entry/2021/01/18/kaimono-swift-ui SwiftUI を活⽤した「レシピ」×「買い物」の新機能開発
ΫοΫύουΞϓϦʮങ͍ػೳʯͷ։ൃ • Feature ModuleͷҰͭͱͯ͠ػೳ։ൃ • VIPERΞʔΩςΫνϟͷ͏ͪɺView෦ͷΈͰSwiftUI Λར༻͢Δઃܭ • 20203݄͔Β։ൃ (202010݄ʹҰൠϦϦʔε)
• ࠷αϙʔτOSiOS 13.3
ΫοΫύουΞϓϦʮങ͍ػೳʯͷ։ൃ • Kaimono ϞδϡʔϧԼͷίʔυߦ • 45,953ߦ (ΫοΫύουiOSશମͷ15%) • UIHostingViewControllerͰϥοϓ͞ΕͨRootView •
35ը໘ • ผϑΝΠϧʹΓग़͞ΕͨSwiftUIίϯϙʔωϯτ • 149ݸ
None
SwiftUIΛ༻͍ͯ1ؒ։ൃͯ͠Έͯ • എܠ • ։ൃ͍ͯ͠ΔϓϩμΫτͷհ • νʔϜϓϩμΫτͷنײ • SwiftUIΛ༻͍ͯ1ؒ։ൃͯ͠Έͯ
1લͷঢ়گ • iOSDC Japan 2020Ͱൃදͨ͠λΠϛϯά … ͪΐ͏Ͳങ ͍ػೳϦϦʔε࣌ظͩͬͨ
https://speakerdeck.com/yujif/iosdc-japan-2020-day-2-cookpad クックパッドが、⾰新的な⽅法でまったく新しい買い物体験を皆様にお届けします
None
1લͷঢ়گ • SwiftUIͷϝϦοτΛײ͍ͯͨ͡෦ • ίʔυྔ͕ݮΔ • ෳࡶɾଟ༷ͳ݅ʹର͔ͯ͠Γ͘͢ॻ͚Δ • ίϯϙʔωϯτ୯ҐͰ͍ճ͠ɾվม͕͍͢͠
ΞϓϦΛϦϦʔε͔ͯ͠Β1։ൃ͍ͯ͘͠தͰͷมԽ • ίʔυϕʔεͷڊେԽ • Feature ModuleͷதͰίʔυߦVIPERγʔϯ࠷େʹ • iOS 14ɾiOS 15ͷϦϦʔε
• iOS 13ɺ14ɺ15ͷ3όʔδϣϯαϙʔτʹ • νʔϜͷ֦େ • ϝΠϯͰ։ൃ͢ΔΤϯδχΞ૿͑ͨ • ΠϯλʔϯੜܞΘΔΑ͏ʹ
1։ൃͯ͠Έͯײ͍ͯ͡Δ՝ • iOS 13ରԠʹΑΔফগͳ͔Βͣൃੜ͢Δ • iOS 13͚ͩڍಈ͕ҧ͏෦͕গͳ͔Βͣ͋Δ • ύϑΥʔϚϯεΛ٘ਜ਼ʹ͍ͯ͠ΔՕॴ݁ߏ͋Δ •
LazyV/HStackɺLazyV/HGrid͑ͯͳ͍😢
1։ൃͯ͠Έͯײ͍ͯ͡Δ՝ • ॊೈੑ͕ߴ͍ͨΊɺUIͷΈํ͕ਓʹΑͬͯมΘΔ • ྫ: ཁૉΛॏͶ͍ͨͱ͖ͷZStackɺbackgroundɺ overlayͷ͍͚ • ྫ: εϖʔεͷ։͚ํ
• ίϯϙʔωϯτׂͷཻ
Q: ࠓޙSwiftUIΛऔΓೖΕͨ։ൃ Λ͢Δʁ ৭ʑফ ײͯͦ͡͏͚ͩͲ…?
Q: ࠓޙSwiftUIΛऔΓೖΕͨ։ൃ Λ͢Δʁ A: Yes
ࠓޙSwiftUIΛऔΓೖΕͨ։ൃΛ͢Δʁ ෆ֬ఆͳϢʔβʔମݧΛ͍ͪૣཱ֬͘͢ΔͨΊʹ ʮ࡞Γ͍͢ɾյ͍͢͠ʯͷॏཁ SwiftUIΛ͏͜ͱͰ໌Β͔ʹ͜ͷ෦ૣ͘ͳ͍ͬͯΔ
ࠓޙSwiftUIΛऔΓೖΕͨ։ൃΛ͢Δʁ ࠓޙνʔϜͰSwiftUIΛ࠾༻͍ͯͨ͘͠Ίʹ… SwiftUIΛͬͯײ͍ͯ͡Δ՝Λ ҰͭͣͭऔΓআ͍͍͖͍ͯͨ💪
ಡΈͯ͘͢อक͍͢͠ SwiftUIͷઃܭʹ͍ͭͯߟ͑Δ
今⽇のトピックでは取り扱いません
αʔϏεಛੑΛߟ͑Δ • ʮ͔͍ͷʯλϒͷߏجຊॎεΫϩʔϧͷը໘ • Viewߏஙͷࡍͷجຊܗͱͯ͠ScrollViewͷதʹཁૉ Λ٧Ί͍ͯ͘ը໘͕΄ͱΜͲ
αʔϏεಛੑΛߟ͑Δ • ෳࡶଟ༷ͳঢ়ଶ • ྫ: จޙͷड͚औΓʹؔ͢Δঢ়ଶ
αʔϏεಛੑʹجͮ͘՝ • ը໘͕ॎʹ͘ͳΓ͍͢ • ίϯϙʔωϯτͷཻॻ ͖ํ͕౷Ұ͞Εͯͳ͍ͱಡ Έʹ͍͘ • ঢ়ଶ͕૿͑Δͱɺذͦͷ ૿͑Δ
ಡΈ͘͢อक͍͢͠ઃܭ • ઃܭʹݸਓ͕ࠩ͋·Γग़ͳ͍Α͏ʹ͍ͨ͠ • ͕݅ෳࡶʹͳͬͯಡΊΔΑ͏ʹ͓͖͍ͯͨ͠ • ͕݅ෳࡶͳը໘ͷอकΛ༰қʹ͍ͨ͠ • ྑ͍ઃܭͷҙࣝΛνʔϜʹਁಁ͍ͤͨ͞
౷Ұͨ͠ॻ͖ํͰϨΠΞτΛઃܭ͢ΔͨΊʹ • ಡΈͯ͘͢อक͍͢͠ઃܭʹ͍ͭͯߟ͑ͨࣄ ◦ ౷Ұͨ͠ॻ͖ํͰϨΠΞτΛઃܭ͢ΔͨΊʹ ◦ ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ ◦ ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ
౷Ұͨ͠ॻ͖ํͰϨΠΞτΛઃܭ͢ΔͨΊʹ • RootViewͷbodyʹॻ͖͘༰Λఆ͍ٛͨ͠ • ίϯϙʔωϯτԽͷཻʹؔͯ͠ڞ௨ೝࣝΛͱΓ͍ͨ
ϨΠΞτΈʹؔͯ͠ struct KaimonoCartView: View { var body: some View {
ScrollView { orderDeliverySection cartPriceSection pickupNameSettingSection deliveryInformationSection pickupStepsSection } } }
ϨΠΞτΈʹؔͯ͠ • ը໘Λҙຯͷ͋Δ·ͱ·ΓͰSectionʹׂ • ෳίϯϙʔωϯτΛͱΓ·ͱΊΔ • ίϯϙʔωϯτؒͷϚʔδϯௐΛ ߦ͏ͨΊͷϨΠϠʔ
ϨΠΞτΈʹؔͯ͠ • ը໘Λҙຯͷ͋Δ·ͱ·ΓͰSectionʹׂ • ׂͨ͠SectionRootViewʹඥͮ͘ (ෳը໘Ͱར༻͠ͳ͍) • SectionΛෳը໘Ͱ͍ͨ͘ͳͬͨ ΒίϯϙʔωϯτԽͷཻΛݟ͢
SectionͷׂҐஔͷܾΊํ • σβΠφʔͱ૬ஊ͠ͳ͕ΒηΫγϣϯׂҐஔ ΛܾΊΔΑ͏ʹ͢Δ • Figma্ͰσβΠϯελΠϧʹԊͬͯάϧʔ ϐϯά͞Ε͍ͯΔͷͰɺσβΠφʔͷҙਤΛ өͭͭ͠Sectionׂ
None
Atoms Molecules Moleculesͷू߹ମ Organisms ProductTile ProductsGrid PopularProductsSection
ίϯϙʔωϯτʹؔͯ͠ • ίϯϙʔωϯτԽ͢Δͷʹؔͯ͠ผϑΝΠϧʹΓग़͠ • ཻ • ΞτϛοΫσβΠϯͰݴ͏Molecules • ୯ମMoleculesΛෳฒͨঢ়ଶͷͷ※ΛίϯϙʔωϯτԽ •
AtomsϨϕϧͷίϯϙʔωϯτԽͯ͠·ͤΜ
ίϯϙʔωϯτʹؔͯ͠ • ίϯϙʔωϯτͷཻʹؔͯ͠νʔϜͰೝ͕ࣝऔΕ͍ͯΔͱί ϛϡχέʔγϣϯ͕ͱΓ͍͢ • Sectionͱͯ͠RootViewʹඥͮ͘ܗͰ༻ҙ͖͢ͷ • ίϯϙʔωϯτͱͯ͠Γग़͖͢ͷ • ίϯϙʔωϯτͱͯ͠Γग़͢߹
• Ͳ͜·Ͱࡉׂ͔͘͢Δͷ͔
ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ • ಡΈͯ͘͢อक͍͢͠ઃܭʹ͍ͭͯߟ͑ͨࣄ ◦ ౷Ұͨ͠ॻ͖ํͰϨΠΞτΛઃܭ͢ΔͨΊʹ ◦ ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ ◦ ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ
ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ
ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ struct KaimonoDeliveryDetailView: View { var body: some View {
ScrollView { switch dataSource.delivery.deliveryStatus { case .accepting: headerSection pickupNameSection orderedProductsSection if shouldShowPickupGuide { pickupGuideSection } // Sectionͷτϧπϝ acceptedButtonSection ordersSection case .preparing: // ུ } } } }
ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ • RootViewͷbodyʹSectionΛྻڍ͢ΔΑ͏ʹͨ͜͠ͱͰ ݟ௨͕͠ྑ͍ • ঢ়ଶʹԠͨ͡Sectionͷग़͚͠ɺಛఆ݅ʹԠ͡ ͨSectionͷτϧπϝ͔Γ͍͢ • body͕ը໘ϨΠΞτͷઃܭਤͱͯ͠ػೳ͢Δ
ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊʹ • ίʔυ্Ͱͷݟ௨͘͢͠͠ͳ͕ͬͨ… • ෳͷ݅Λߟྀͨ͠ը໘ʹ͓͚ΔϢʔβʔঢ়ଶͷ࠶ݱ ͍͠ • ը໘͕յΕ͍ͯͳ͍͜ͱΛಈ࡞֬ೝ͢Δ • ࣮ʹೖΔ·Ͱʹ֘ը໘ΛදࣔͰ͖ΔΑ͏ʹͳΔ
·Ͱ͕͔͔࣌ؒΔ
ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊͷऔΓΈ
https://speakerdeck.com/aomathwift/ji-neng-gotonidong-zuo- suruminiapuridepurebiyusaikuruwobao-su-nisitahua 機能ごとに動作するミニアプリでプレビューサイクルを爆速にした話
ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊͷऔΓΈ
ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊͷऔΓΈ extension SandboxScene { static let kaimonoTopForJustSetupCompleted = SandboxScene(sceneName: "τοϓʢडऔॴઃఆࡁɾະจʣ")
{ initializer in let environment = StubbableEnvironment() initializer.initialize(environment) environment.registerClientResponses(fixtures, overrideFixtures: [ .orders(.empty), .userOrderedDeliveries(.empty), ]) ɹ let viewController = KaimonoTopViewBuilder.build(environment: environment) return viewController } static let kaimonoTopForDeliveriesUnavailable = SandboxScene(sceneName: "τοϓʢۙͷૹͳ͠ʣ") { initializer in // ུ } } private let fixtures: [Fixture] = [ .cart(.normal), .promotedDeliveryProducts(.ordinary), .me(.userLocation), .feature(.popularProducts), // ུ ]
ਖ਼֬ʹಈ࡞ͤ͞ΔͨΊͷऔΓΈ private let fixtures: [Fixture] = [ .cart(.normal), .promotedDeliveryProducts(.ordinary), .me(.userLocation),
.feature(.popularProducts), // ུ ] environment.registerClientResponses(fixtures, overrideFixtures: [ .orders(.empty), .userOrderedDeliveries(.empty), ]) • ը໘දࣔʹඞཁͳϨεϙϯεελϒΛFixtureԽ • ϕʔεͷFixtureͱɺ݅͝ͱͷoverrideFixturesΛ༻ҙ • ϛχΞϓϦͷ݅͝ͱͷը໘දࣔΛ؆୯ʹఆٛͰ͖ΔΑ͏ʹ
ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ • ಡΈͯ͘͢อक͍͢͠ઃܭʹ͍ͭͯߟ͑ͨࣄ ◦ ౷Ұͨ͠ॻ͖ํͰϨΠΞτΛઃܭ͢ΔͨΊʹ ◦ ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ ◦ ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ
ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ • υΩϡϝϯτԽ • υΩϡϝϯτඋձ • ݟ·ͱΊࣾϒϩά • SwiftUIϨΠΞτʹؔ͢Δௐࠪ •
ઃܭʹ͍ͭͯޠΔձ
ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ
ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ
ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ
ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ
ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ
·ͱΊ • ౷Ұͨ͠ॻ͖ํͰϨΠΞτΛઃܭ͢ΔͨΊʹ • ϨΠΞτઃܭΛ౷ҰԽ • ίϯϙʔωϯτԽͷཻΛ໌֬ʹ • ෳࡶɾଟ༷ͳ݅ʹରॲ͢Δ •
ը໘ϨΠΞτͷઃܭਤͱͯ͠RootViewͷbodyΛར༻ • ಈ࡞֬ೝͷͨΊʹϛχΞϓϦΛ׆༻ • ྑ͍ઃܭͷҙࣝΛνʔϜਁಁ͢ΔͨΊʹ • ఆظతʹઃܭʹ͍ͭͯٞ͢ΔΛઃ͚Δ • υΩϡϝϯτԽ͢Δ͜ͱʹΑͬͯڞ௨ೝࣝΛऔΔ