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の進化に ついていくためにやったこと
Search
Recruit
PRO
August 31, 2023
Business
6
5.1k
SwiftUIの進化に ついていくためにやったこと
iOSDC Japan 2023 での中島の発表資料です。
Recruit
PRO
August 31, 2023
Tweet
Share
More Decks by Recruit
See All by Recruit
Browser
recruitengineers
PRO
9
2.7k
JavaScript 研修
recruitengineers
PRO
8
1.7k
TypeScript入門
recruitengineers
PRO
36
12k
モダンフロントエンド 開発研修
recruitengineers
PRO
11
6.7k
Webアクセシビリティ入門
recruitengineers
PRO
4
1.7k
攻撃と防御で実践するプロダクトセキュリティ演習~導入パート~
recruitengineers
PRO
4
2.1k
モバイルアプリ研修
recruitengineers
PRO
6
1.9k
事業価値と Engineering
recruitengineers
PRO
8
6k
制約理論(ToC)入門
recruitengineers
PRO
10
4.2k
Other Decks in Business
See All in Business
【会社紹介資料】株式会社エーピーコミュニケーションズ
apcom
0
5.8k
Findy社0901イベント資料(note株式会社)
yamane
0
460
エンジニア職/新卒向け会社紹介資料(テックファーム株式会社)
techfirm
1
4.7k
「みんな、笑顔になぁれ」を実現する 職種混合開発組織の目標設定・評価の改善事例
daitasu
0
230
【エンジニア職】中途採用向け会社説明資料(テックファーム株式会社)
techfirm
0
5.5k
株式会社スムーズ会社紹介資料/Smooth COMPANY DECK
smoothinc
PRO
1
1.2k
enechain company deck
enechain
PRO
9
130k
セーフィー株式会社(Safie Inc.) 会社紹介資料
safie_recruit
6
370k
250830 RubyKaigi 2025 follow up 株式会社iCAREスポンサーLT「健康診断 follow up」
msykd
PRO
1
210
ARI会社説明
arisaiyou
1
16k
新規投資家向け資料20250815
junkiogawa
0
2.8k
「使いこなせないかも…」を超えて、BackLogを日常にするまでの話(JBUG Live版)
sho_okawara
0
140
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
BBQ
matthewcrist
89
9.8k
Automating Front-end Workflow
addyosmani
1370
200k
Writing Fast Ruby
sferik
628
62k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.1k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
How to Think Like a Performance Engineer
csswizardry
26
1.9k
Into the Great Unknown - MozCon
thekraken
40
2k
Mobile First: as difficult as doing things right
swwweet
224
9.9k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Why Our Code Smells
bkeepers
PRO
339
57k
Transcript
@motoshima1150 iOSDC 2023 SwiftUIの進化に ついていくためにやったこと
このセッションのねらい 『スタディサプリ 中学講座』がSwiftUIと共に歩んできた道を振り返りました。 ポイント1 直面した課題の例として 具体的にAlert, NavigationViewの進化を知る SwiftUIのような進化の早いフレームワークと どのように付き合うのかを考える ポイント2
Agenda | 01 02 03 04 発表者紹介 SwiftUIと『スタディサプリ 中学講座』 SwiftUIの実践的な書き換え
まとめ
発表者紹介 01
@motoshima1150 / 中島元成 - iOS アプリエンジニア - 『スタディサプリ 中学講座』開発を担当 -
🍺, 🏕, "3dメガネ アイコン" by DesignBolts is licensed underCC BY 4.0
(株)リクルートでの位置づけ 創業 本社 事業の売上収益 従業員数 2012年 10月1日 株式会社リクルートホールディングス設立時の 分社化により設立 2018年
4月1日 株式会社リクルートに商号変更 東京 7,606億円 (2022年4月1日~2023年3月31日) 19,836人 (2023年4月1日現在 / アルバイト・パート含) OUR VISION
サービスラインナップ 様々なサービスラインナップにて事業展開をしています スタディサプリ 対象学年 小・中学校 高校 大学・社会人 オンラインビデオ (B to
C) オンラインビデオ& アセスメント (B to B to C) オンラインコーチング パーソナルコーチプラン
SwiftUIと『スタディサプリ 中学講座』 02
SwiftUI 年表 と『スタディサプリ 中学講座』 WWDC19 WWDC20 WWDC21 WWDC22 WWDC23 SwiftUI発表
SwiftUIベースのアプリ構築が可能に Listや検索の大幅強化 .searchable modifierの追加 .refreshable modifierの追加 .swipeActions modifierの追加 NavigationStackの追加 Charts フレームワークの追加 Photos フレームワークの追加 KeyframeAnimation @Observable の追加 MapKit の強化 SwiftDataのサポート リニューアルリ リース リニューアル 開始
『スタディサプリ 中学講座』はSwiftUIと共に歩んでいる
どのような課題が発生したか • 既存実装が非推奨となり、将来的に廃止されてしまう ◦ Alert, NavigationLink • 新規APIが公開されるが、対応バージョン要件を満たせず導入できない ◦ NavigationStack
Alert, Navigationのケースで書き換えをご紹介いたします
… 『スタディサプリ 中学講座』の構成 スタディサプリ 中学講座 project Core: 依存関係や共通処理を持つ UIComponent: 共通UIやDesignSystem
の token などを持つ JuniorHighSchool: 実際の画面単位でサブモジュールを用意 MyPage StudyReport … マルチモジュール構成に移行中。各モジュール間は独立した実装が可能になっています。 コラム
SwiftUIの実践的な書き換え 03
@State private var showAlert = false var body: some View
{ Button("Tap to show alert") { showAlert = true } .alert(isPresented: $showAlert) { Alert( title: Text("Current Location Not Available"), message: Text("Your current location can’t be " + "determined at this time.") ) } } struct Login: View {すprivate var didFail = false let alertTitle: String = "Login failed." var body: some View { LoginForm(didFail: $didFail) .alert( alertTitle, isPresented: $didFail ) { Button("OK") { // Handle the acknowledgement. } } } } • Alert viewが廃止となり、より扱いやすくなっている。 Alert の進化 iOS 13.0–17.0 Deprecated iPadOS 13.0–17.0 Deprecated https://developer.apple.com/documentation/swiftui/ iOS 15.0+ iPadOS 15.0+
『スタディサプリ 中学講座』でのAlert用途 • ユーザーに向けて通信エラーを伝える • 学習を離脱するなどのユーザー状態が破棄される前の確認 • 強制バージョンアップやメンテナンスなどの強制力の強いユーザー告知
Alert の書き換え .background( EmptyView().alert( isPresented: $isFirstAlertPresented, content: { Alert(title: Text("First
alert"), message: Text("Alert message")) } ) ) .alert( "First alert", isPresented: $isFirstAlertPresented, actions: { }, message: { Text("Alert message") } ) 旧APIでは1つのViewに対して、複数のAlert modifierを付与した際に表示されない動作の 回避として利用
NavigationView Navigation APIの進化 iOS 13.0–17.0 Deprecated iPadOS 13.0–17.0 Deprecated iOS
16.0+ iPadOS 16.0+ @State private var isShowingPurple = false @State private var isShowingPink = false @State private var isShowingOrange = false var body: some View { NavigationView { List { NavigationLink("Purple", isActive: $isShowingPurple) { ColorDetail(color: .purple) } NavigationLink("Pink", isActive: $isShowingPink) { ColorDetail(color: .pink) } NavigationLink("Orange", isActive: $isShowingOrange) { ColorDetail(color: .orange) } } } .navigationViewStyle(.stack) } // Nothing on the stack by default. @State private var path: [Color] = [] var body: some View { NavigationStack(path: $path) { List { NavigationLink("Purple", value: .purple) NavigationLink("Pink", value: .pink) NavigationLink("Orange", value: .orange) } .navigationDestination(for: Color.self) { color in ColorDetail(color: color) } } } https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types NavigationStack
『スタディサプリ 中学講座』でのNavigation用途 • Push遷移(2−3階層) • プログラムで制御された Push遷移 • 1画面から複数の種類の遷移先
NavigationView → NavigationStack の書き換え NavigationView { CourseScreen() } struct CourseScreen:
View { ... @State var isActive = false @State var selectedTopicID = "" var body: some View { ZStack { NavigationLink(isActive: $isActive) { TopicScreen(topicID: selectedTopicID) } label: { EmptyView() } VStack { ForEach(course.topicIDs, id: \.self) { id in Button("topic id: \(id)") { selectedTopicID = id isActive = true } } } } ... } } NavigationStack { CourseScreen() } struct CourseScreen: View { ... @State var isActive = false @State var selectedTopicID = "" var body: some View { VStack { ForEach(course.topicIDs, id: \.self) { id in Button("topic id: \(id)") { selectedTopicID = id isActive = true } } } .navigationDestination(isPresented: $isActive) { TopicScreen(topicID: selectedTopicID) } ... } } 不自然なZStackとNavigationLinkが消えてスッキリ
運用状況
1. Issueを作成し、課題としてチーム内共有する。 2. 動作確認の担保、書き換え方針を共有する。 3. 品質改善の時間で実際にコードの書き換えを行う。 計画
• 課題をオープンにすることで、以下のメリットを受けています。 ◦ 目につくので忘れない ◦ いつでも見返せる ◦ 対応時期のコミュニケーションが容易 1. Issueを作成し、課題としてチーム内共有する。
• MagicPodを用いたE2Eテストを導入しています。 ◦ 画面遷移などの書き換えも安心して書き換えができます。 • 書き換えの方針などを事前共有によってチーム内で検証します。 2. 動作確認の担保、書き換え方針を共有する。
私たちのチームでは品質改善に向けた実装時間が確保されています。 • Quality Budget ◦ 2週間に1日品質改善に寄与する issueを消化する日を設けています。 • KAIZEN ◦
小中高プロダクトiOSチームでプロダクトを跨いでペアを組み、 週に1回1時間程度品質改善に当てる。 3. 品質改善の時間で実際にコードの書き換えを行う。
• 『スタディサプリ』は年に1回バージョン更新を行なっています。 ◦ 今年の4月にiOS 14をサポートバージョンから外しました。 ◦ シェア率を参照しながらPdMとすり合わせを行い更新しています。 • これから導入を控えているもの。 今後の予定は
https://developer.apple.com/documentation/swiftui/navigationstack https://developer.apple.com/documentation/swiftui/view/presentationdetents(_:)
まとめ 04
私たちはSwiftUIの進化を追いながら、落ち着いて取捨選択ができたと思います。 書籍「進化的アーキテクチャ」と照らし合わせ要因を振り返りました。 要因 • 年一回のサポートバージョンの見直しタイミングがある ◦ 腐敗防止層の対策が立てやすい • モジュール分割により、新しいコードは新しい設計で書くことができる ◦
漸進的な改善を行うことができる • メインタスクとは別で品質改善のために取り組む時間がある ◦ 心理的にも余裕が生まれる 運用を通しての振り返り
最後に『スタディサプリ 中学講座』で得たまなび 私たちのSwiftUIという選択は、2020年時点では将来性のリスクを取ることだったと思 います。 導入時点ではどれも予測のつかない変化でしたが、その点で過剰に忌避するのでは なく、ワークアラウンドな対応なども受け入れながらSwiftUIの進化に合わせて一緒に 進化しつつ、導入タイミングはプロダクトでハンドリングできる基盤を整えておくことの 重要性を改めてまなぶことができました。
その他 弊社についてのご紹介 以下リンク先でもプロダクト開発部について紹介しています。ぜひご覧ください。 ・スタディサプリ プロダクトチーム ブログ スタディサプリ Product Team Blog 発表資料
- スタディサプリ Product Team Blog ※エンジニア / デザイナー / TPMが記事を書いています ・ブランドサイト スタディサプリ BRAND SITE ・採用ページはこちら キャリア | スタディサプリ BRAND SITE ・カジュアル面談はこちらからお気軽にご応募ください スタディサプリエンジニア職種カジュアル面談エントリーフォーム
一緒に事業拡大を目指す仲間を お待ちしています!
ご清聴ありがとうございました