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.4k
SwiftUIの進化に ついていくためにやったこと
iOSDC Japan 2023 での中島の発表資料です。
Recruit
PRO
August 31, 2023
Tweet
Share
More Decks by Recruit
See All by Recruit
事業の財務責任に向き合うリクルートデータプラットフォームのFinOps
recruitengineers
PRO
2
180
AI-DLCを現場にインストールしてみた:プロトタイプ開発で分かったこと・やめたこと
recruitengineers
PRO
2
250
プロダクトマネジメントの分業が生む「デリバリーの渋滞」を解消するTPMの越境
recruitengineers
PRO
3
880
あなたの知らない Linuxカーネル脆弱性の世界
recruitengineers
PRO
4
330
dbtとBigQuery MLで実現する リクルートの営業支援基盤のモデル開発と保守運用
recruitengineers
PRO
5
260
『ホットペッパービューティー』のiOSアプリをUIKitからSwiftUIへ段階的に移行するためにやったこと
recruitengineers
PRO
4
1.8k
経営の意思決定を加速する 「事業KPIダッシュボード」構築の全貌
recruitengineers
PRO
4
420
Browser
recruitengineers
PRO
12
4.1k
JavaScript 研修
recruitengineers
PRO
9
2.2k
Other Decks in Business
See All in Business
SimpleForm 会社紹介資料
simpleform
2
50k
エニグモ_会社紹介資料
enigmo_hr
0
2.4k
インキュデータ会社紹介資料
okitsu
3
48k
株式会社メディアドゥ 採用ピッチ資料
mediado
0
390
フルカイテン株式会社 採用資料
fullkaiten
0
79k
Fuji Oil 2025 Board of Directors
tsogo817421
2
340
AIがコードを書く時代にエンジニア組織が事業に貢献する仕組み / How engineering organizations can contribute to business in an age where AI writes code
bpstudy
0
120
サムコ株式会社 第47期第1四半期決算概要
tsuchihashi
0
240
QuackShift 会社紹介資料
riekondo
0
190
メドピアグループ紹介資料
medpeer_recruit
10
140k
Bakuraku Product Manager Team Deck
layerx
PRO
3
1.6k
生成AI専任営業が語るre:Inventで発表された生成AIアップデート情報
suzakiyoshito
0
240
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
273
21k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.1k
Designing for humans not robots
tammielis
254
26k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.2k
[SF Ruby Conf 2025] Rails X
palkan
0
560
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.3k
Marketing to machines
jonoalderson
1
4.3k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
0
1.8k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
1
200
Documentation Writing (for coders)
carmenintech
77
5.2k
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 ・カジュアル面談はこちらからお気軽にご応募ください スタディサプリエンジニア職種カジュアル面談エントリーフォーム
一緒に事業拡大を目指す仲間を お待ちしています!
ご清聴ありがとうございました