Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SwiftUIの進化に ついていくためにやったこと
Search
Recruit
PRO
August 31, 2023
Business
6
5.3k
SwiftUIの進化に ついていくためにやったこと
iOSDC Japan 2023 での中島の発表資料です。
Recruit
PRO
August 31, 2023
Tweet
Share
More Decks by Recruit
See All by Recruit
あなたの知らない Linuxカーネル脆弱性の世界
recruitengineers
PRO
4
230
dbtとBigQuery MLで実現する リクルートの営業支援基盤のモデル開発と保守運用
recruitengineers
PRO
4
210
『ホットペッパービューティー』のiOSアプリをUIKitからSwiftUIへ段階的に移行するためにやったこと
recruitengineers
PRO
4
1.7k
経営の意思決定を加速する 「事業KPIダッシュボード」構築の全貌
recruitengineers
PRO
4
370
Browser
recruitengineers
PRO
12
3.9k
JavaScript 研修
recruitengineers
PRO
9
2.2k
TypeScript入門
recruitengineers
PRO
37
15k
モダンフロントエンド 開発研修
recruitengineers
PRO
16
8.2k
Webアクセシビリティ入門
recruitengineers
PRO
5
2.3k
Other Decks in Business
See All in Business
데이터 분석가 없이 데이터 드리븐 디자인하기 | 2025년 11월 세미나
datarian
0
1.6k
Speee_2025年9月期 通期決算説明資料
speee_pr
0
530
株式会社TVer 会社紹介資料
techtver
PRO
9
95k
イクシアス株式会社 会社紹介資料
ixyas
0
2.5k
スマートキャンプ株式会社 会社紹介資料 / companydeck
smartcamp
1
2.5k
CREALを知る
creal
PRO
0
630
2025.11_中途採用資料.pdf
superstudio
PRO
3
89k
Srush Corporate Brand Book
tomomifuruya
1
9.2k
ログラス会社紹介資料 新卒採用 ビジネス職[経営幹部候補]/ Loglass Company Deck
loglass2019
1
12k
AIエージェントウェビナー_20251118_suzaki
suzakiyoshito
0
330
自らを強いエンジニアにするための3つの習慣 2025/ Fitter happier more productive
shinyorke
PRO
0
210
株式会社CINC 会社案内/Company introduction
cinchr
6
70k
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1371
200k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.6k
We Have a Design System, Now What?
morganepeng
54
7.9k
Why Our Code Smells
bkeepers
PRO
340
57k
Building Applications with DynamoDB
mza
96
6.8k
4 Signs Your Business is Dying
shpigford
186
22k
A Tale of Four Properties
chriscoyier
162
23k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Docker and Python
trallard
46
3.7k
Making Projects Easy
brettharned
120
6.5k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
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 ・カジュアル面談はこちらからお気軽にご応募ください スタディサプリエンジニア職種カジュアル面談エントリーフォーム
一緒に事業拡大を目指す仲間を お待ちしています!
ご清聴ありがとうございました