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
レガシーなiOSアプリのSwift化 〜5年分の成功と失敗事例〜
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
tinpay
January 09, 2024
Programming
320
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
レガシーなiOSアプリのSwift化 〜5年分の成功と失敗事例〜
tinpay
January 09, 2024
More Decks by tinpay
See All by tinpay
モバイルアプリ開発チームをプラットフォームチームで分割した話
shoheifukui
0
610
iOSアプリの 大きな技術的負債に立ち向かう
shoheifukui
1
1.3k
モバイルアプリでのFeatureFlagの導入
shoheifukui
0
680
ShareExtensionをためす
shoheifukui
2
1.8k
Other Decks in Programming
See All in Programming
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
260
Performance Engineering for Everyone
elenatanasoiu
0
210
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
180
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.5k
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
210
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
910
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
130
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
110
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
4.5k
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.5k
Claspは野良GASの夢をみるか
takter00
0
210
Featured
See All Featured
Game over? The fight for quality and originality in the time of robots
wayneb77
1
200
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
330
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
620
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Become a Pro
speakerdeck
PRO
31
6k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Mobile First: as difficult as doing things right
swwweet
225
10k
How STYLIGHT went responsive
nonsquared
100
6.2k
Believing is Seeing
oripsolob
1
150
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
860
A designer walks into a library…
pauljervisheath
211
24k
Transcript
福井 章平 2023年10月24日 Chatwork Product Day レガシーなiOSアプリのSwift化 〜5年分の成功と失敗事例〜
自己紹介 2 • 名前:福井 章平 (@tinpay) ◦ 2014年 入社 (iOSアプリエンジニア)
• 役職:プロダクト本部 モバイルアプリケーション開発部 マネージャー • 趣味 ◦ 大阪のスパイスカレー屋さん巡り ◦ ビール
今日お話しする内容 • 先日、「Chatwork」iOS版アプリが完全にSwift言語で書き直され、古いObjective-Cの コードは一切なくなりました。この大変な作業には約 5年の時間がかかりました。コードの 量が多かったことも時間がかかった理由の一つですが、他にもいくつかの課題がありま した。今日は、「Chatwork」iOS版アプリの開発の歴史と、Swiftへの移行で出てきた問 題点についてお話しします。 • さらに、現在のiOS版アプリ開発チームがどのような作業を行っているのかも一緒にご紹
介します。
AGENDA アジェンダ 「Chatwork」iOS版アプリの歴史 Swift化を始める前の大きな課題 Swiftへの移行プロセス 移行時に出てきた課題 現在のiOS版アプリ 1 2 3
4 5
5 「Chatwork」iOS版アプリの歴史 1
「Chatwork」モバイル版アプリの歴史 6 2011 2013 2011-9-29 iOS v1.0 リリース (Titanium) 2015
2013-9-9 iOS v2.5 Robson リリース (Titanium) 2013-2-5 iOS v2.0 Fujiyama リリース (Titanium) 2014-1-27 iOS v3.0 Rocky リリース (Titanium) 2017 2019 2016-6-7 iOS v4.0 Eiger リリース (Objective-C) 2021 2022-5-12 iOS v6.0 リリース (Objective-C, Swift) 2018-5-21 iOS v4.30 MaunaLoa リリース (Objective-C, Swift) 2023 2023-8 フルSwift化 完了 2020-3-2 iOS v5.0 リリース (Objective-C, Swift) ファーストリリースから約12年!
「Chatwork」モバイル版アプリの歴史(前半) 7 2011 2013 2011-9-29 iOS v1.0 リリース (Titanium) 2015
2013-9-9 iOS v2.5 Robson リリース (Titanium) 2013-2-5 iOS v2.0 Fujiyama リリース (Titanium) 2014-1-27 iOS v3.0 Rocky リリース (Titanium)
「Chatwork」モバイル版アプリの歴史(後半) 8 2017 2019 2016-6-7 iOS v4.0 Eiger リリース (Objective-C)
2021 2022-5-12 iOS v6.0 リリース (Objective-C, Swift) 2018-5-21 iOS v4.30 MaunaLoa リリース (Objective-C, Swift) 2023 2023-8 フルSwift化 完了 2020-3-2 iOS v5.0 リリース (Objective-C, Swift)
Titaniumアプリの時代 (Rocky: 2014年1月27日 リリース) 9
ネイティブアプリへ (Eiger: 2016年6月7日 リリース) 10
現在の「Chatwork」モバイル版アプリ 11
「Chatwork」モバイル版アプリとiPhoneの歩み 12 2011 2013 2011-9-29 iOS v1.0 リリース (Titanium) 2015
2013-9-9 iOS v2.5 Robson リリース (Titanium) 2013-2-5 iOS v2.0 Fujiyama リリース (Titanium) 2014-1-27 iOS v3.0 Rocky リリース (Titanium) 2017 2019 2016-6-7 iOS v4.0 Eiger リリース (Objective-C) 2021 2022-5-12 iOS v6.0 リリース (Objective-C, Swift) 2018-5-21 iOS v4.30 MaunaLoa リリース (Objective-C, Swift) 2023 2023-8 フルSwift化 完了 2020-3-2 iOS v5.0 リリース (Objective-C, Swift) iOS5 iOS6 iOS4 iOS7 iOS8 iOS9 iOS10 iOS11 iOS12 iOS13 iOS14 iOS15 iOS16 iOS17 最新OS Retina App Folders Notification Center iMessage Apple Maps Siri Passbook Panorama Photo Flat Design Control Center AirDrop Handoff Interactive Notifications Third Party Keyboard iCloud Drive 低電力 モード Night Shift iMessager Sticker 3D Touch Home App ファイル QRコード スキャン 片手 キーボード Live Photos スクリーン タイム Siri Shortcuts Apple TV App Dark Mode Shortcut App Widget App ライブラリ P in P 集中モード アプリ間 D & D アプリごと テキストサイズ iPhoneを Webカメラ ロック画面 Widget スタンバイ PDF 書き込み Swift4 Swift5 Swift4.1 Swift4.2 Swift5.1 Swift5.2 Swift5.3 Touch ID ARC AutoLayout Storyboard Swift1 Swift2 Swift3 SwiftUI Combine Swift5.4 Swift5.5 Swift Concurrency Xcode Cloud マルチタスク FaceTime Swift5.6 Swift5.7 Swift5.8 Swift5.9 Swift Package iPhone 新機能 iOS 新技術 TestFlight
「Chatwork」モバイル版アプリと「Chatwork」新機能の歩み 13 2017 2019 2011-9-29 iOS v1.0 リリース (Titanium) 2011
2013-9-9 iOS v2.5 Robson リリース (Titanium) 2013-2-5 iOS v2.0 Fujiyama リリース (Titanium) 2014-1-27 iOS v3.0 Rocky リリース (Titanium) 2013 2015 2016-6-7 iOS v4.0 Eiger リリース (Objective-C) 2021 2022-5-12 iOS v6.0 リリース (Objective-C, Swift) 2018-5-21 iOS v4.30 MaunaLoa リリース (Objective-C, Swift) 2023 2023-8 フルSwift化 完了 2020-3-2 iOS v5.0 リリース (Objective-C, Swift) Chatwork Live iPad対応 Chatwork Live (音声通話) タスク 〆切時間設定 リアクション マルチアカウント ブックマーク Apple/Google ログイン/登録 名刺読み取り機能 プッシュ通知 本文表示 Chatwork Live 画面共有 リンクプレビュー ダークモード ロゴリニューアル 通知しない 曜日・時間帯設定 ミュート機能 UI刷新 iOSネイティブアプリになっ てから8年の間に リリースした新機能 (一部抜粋) Share Extension
14 Swift化を始める前の大きな課題 2
本格的にSwift化を始める前に大きな課題があった 15 2011 2013 2011-9-29 iOS v1.0 リリース (Titanium) 2015
2013-9-9 iOS v2.5 Robson リリース (Titanium) 2013-2-5 iOS v2.0 Fujiyama リリース (Titanium) 2014-1-27 iOS v3.0 Rocky リリース (Titanium) 2017 2019 2016-6-7 iOS v4.0 Eiger リリース (Objective-C) 2021 2022-5-12 iOS v6.0 リリース (Objective-C, Swift) 2018-5-21 iOS v4.30 MaunaLoa リリース (Objective-C, Swift) 2023 2023-8 フルSwift化 完了 2020-3-2 iOS v5.0 リリース (Objective-C, Swift)
本格的にSwift化を始める前に大きな課題があった 16 2015 2014-1-27 iOS v3.0 Rocky リリース (Titanium) 2017
2019 2016-6-7 iOS v4.0 Eiger リリース (Objective-C) 2021 2020-3-2 iOS v5.0 リリース (Objective-C, Swift) Rocky→Eiger 負債が発生 Eiger→MaunLoa 負債を解消 2018-5-21 iOS v4.30 MaunaLoa リリース (Objective-C, Swift)
本格的にSwift化を始める前に大きな課題があった 17 2015 2017 2019 2021 2020-3-2 iOS v5.0 リリース
(Objective-C, Swift) Rocky→Eiger 負債が発生 Eiger→MaunLoa 負債を解消 2018-5-21 iOS v4.30 MaunaLoa リリース (Objective-C, Swift) 2014-1-27 iOS v3.0 Rocky リリース (Titanium) 2016-6-7 iOS v4.0 Eiger リリース (Objective-C)
RockyからEigerへ 18 Eigerで実現したかったこと • iOSネイティブアプリ化 ◦ 0からObjective-Cでの実装(元はTitanium) • UI/UXの刷新 ◦
iOS7で採用されたフラットデザインに合わせたUI/UX • 新APIへの移行 ◦ Scala化PJで作られる予定の新APIに置き換える ◦ モデルをドメインレベルで再定義し、各モデルを取得するシンプル なAPIを想定 • プッシュ通知の拡張 ◦ すべてのメッセージ投稿において通知可能にする • WYSIWYGエディタの提供 ◦ メッセージ入力欄でタグを表示しないようにする
新APIを使わずに既存APIで進めることになった 19 新APIを使う想定でEigerはつくられていた Scala化PJの方向転換があり、この時点で新APIは作らないという判断 Eigerで新APIを利用する想定で作っていた箇所を、 既存APIを使うようにしないといけない
新APIを使わずに既存APIで進めることになった 20 新APIにあたる処理をEiger内に仮想的に実装して、 既存APIから新APIのレスポンス形式のデータで取得できるようにした 早くリリースすることを最優先
既存APIから新APIのレスポンス形式へ変換 21 新API 新API Client App 既存API 新API Client App
Conversion 仮想 新API 修正前 修正後 サーバー クライアント
リリーススピードを優先して出てきた問題 22 新APIと既存APIとでは設計思想が異なっており、新APIを使 う箇所で歪が生じた Conversion層だけで設計思想の差異を吸収することが困難 • クラッシュ数増加 • パフォーマンス低下 Mantle(JSON-ObjectのMapper)を廃止したり、クラッシュ数
の多かったタイムラインでの非同期処理の見直し、CoreData からRealmへの変更など局所的な対応を行ったが、問題の発生 数はまだまだ多く、根本解決には至らなかった。 改善を試みたが...
Eigerリリース時の負債解消を進めた 23 2015 2017 2019 2021 2020-3-2 iOS v5.0 リリース
(Objective-C, Swift) Rocky→Eiger 負債が発生 2018-5-21 iOS v4.30 MaunaLoa リリース (Objective-C, Swift) 2014-1-27 iOS v3.0 Rocky リリース (Titanium) 2016-6-7 iOS v4.0 Eiger リリース (Objective-C) Eiger→MaunLoa 負債を解消
Eigerの負債解消のために始まったMaunaLoa開発プロジェクト 24 • 目的 ◦ Phase1 ▪ iOS版アプリのコア部分の実装を見直す事により、 クラッシュ数を激減させてアプリを安定させること ◦
Phase2 ▪ タイムラインの安定化
参考) MaunaLoa開発プロジェクト合宿 25 2017年11月8日〜11月10日 伊東にて合宿を行った
参考) MaunaLoa開発プロジェクト合宿 26 合宿でやること • ViewとModelまわりをどのように つなぎこむか検討する • APIの連携をどのように行うか検討 する
• Realmのスレッド管理方法について 検討する • エラーハンドリングの検討する • コーディングの指針の整理する などなど 合宿でやらないこと • モデルの再設計 • 別のアーキテクチャーの選定/調査 • UI /UXについての考察 • Swift置き換えなどの単純作業 / 黙々とコーディング
MaunaLoa Phase1
MaunaLoa Phase1で行ったこと 28 • Conversion層の撤廃 ◦ 既存APIのレスポンスから直接Modelに返還すること で、新APIレスポンスへの返還処理を撤廃した(後述) • Modelの再設計
◦ 既存APIに合わせたModel設計にした • Swift化 ◦ 静的型付け、オプショナル型を採用することで安定性 を向上させる ◦ ここからSwift化が始まる
Conversion層の撤廃 29 既存API 新API Client App Conversion Eiger サーバー クライアント
既存API 既存API Client App MaunaLoa
MaunaLoa Phase1 の具体的な作業内容 30 • 既存API Client作成 • ドメインモデル再設計 •
Realmクライアント / メモリキャッシュ見直し • Application Service作成 • エラーハンドリング再設計 2018年5月21日 MaunaLoa Phase1 リリース
MaunaLoa Phase2
MaunaLoa Phase2で行ったこと 32 • タイムラインの安定化 ◦ 不具合の根本解決を行った ▪ クラッシュ数の軽減 ▪
オフセット位置がずれたり、キーボード周りの不 具合の解消 ▪ タイムラインの根本的な構成からの見直し • タイムラインのSwift化も行うことにした
MaunaLoa Phase2 の具体的な作業内容 33 • タイムラインをSwift化し、RxSwiftに移行 • タイムラインのUnitTest実装 • View/ViewControllerのフロー見直し
• キーボードの再設計 ◦ OSにまかせた実装に寄せる 2019年5月22日 MaunaLoa Phase2 リリース
34 Swiftへの移行プロセス 3
Eiger時代の負債解消(MaunaLoa)がきっかけでSwift化が始まった Swift化の目的 35 • 安定性の向上 ◦ Swiftは型安全言語であり、コンパイル時にエラー を検出できる ◦ オプショナル型
• 可読性と保守性の向上 ◦ Swiftはシンタックスが簡潔で直感的である ◦ モダンな言語機能 • Appleの方向性に沿っている ◦ AppleがSwiftを推進している Swift化の目的
Swift化をどうすすめようとしたか 36 1. Modelレイヤー(API Client, ドメインモデル) 2. タイムライン(View, ViewController, ViewModel)
3. View, ViewController, ViewModelレイヤー MaunaLoa Phase1 MaunaLoa Phase2 Swift化 完了!
Objective-Cの割合の推移 37
MaunaLoa Phase1 開始前 38 既存API 既存API Client Model View ViewModel
Objective-C : 97.3%
MaunaLoa Phase1 リリース 39 ModelレイヤーのSwift化が完了 • API Client • ドメインモデル
• アプリケーションサービス • エラーハンドリング 既存API 既存API Client Model View ViewModel Objective-C : 70.19%
MaunaLoa Phase1の進捗管理 40 MaunaLoa Phase1 はスプレッドシートで機能単位での進捗管理を行ってた
Objective-Cの割合の推移 41 2018-5-21 MaunaLoa Phase1
MaunaLoa Phase2 リリース 42 既存API 既存API Client Model Objective-C :
45.7% View ViewModel タイムラインのSwift化が完了
Objective-Cの割合の推移 43 2018-5-21 MaunaLoa Phase1 2019-5-22 MaunaLoa Phase2
View, ViewController, ViewModelレイヤーのSwift化の進捗管理 44 View, ViewController, ViewModelのファイル単位で進捗管理を行っていた
MaunaLoa Phase2リリースの4年後にSwift化が完了 45 2018-5-21 MaunaLoa Phase1 2023-8 フルSwift化 完了 2019-5-22
MaunaLoa Phase2 全体的になだらかな傾斜 一気に進めることが出来なかった
46 移行時に出てきた課題 4
移行時に出てきた課題 47 1. 優先度の高い機能開発プロジェクトとの並走 2. ASTプロジェクトの難易度の高さ 3. Objective-CとSwiftが混在している 4. 開発メンバーの設計思想の違い
1. 優先度の高い機能開発プロジェクトとの並走
難易度が高く工数がかかるプロジェクトと並行してSwift化を行った 49 2018-5-21 MaunaLoa Phase1 2023-8 フルSwift化 完了 2019-5-22 MaunaLoa
Phase2 タスク 〆切時間設定 リアクション マルチアカウント ブックマーク Apple/Google ログイン/登録 プッシュ通知 本文表示 AST ダークモード iPad対応 通知しない 曜日・時間帯設定 フリープラン 仕様変更
Swift化と機能開発プロジェクトが並走すると… 50 基本的に人員リソースは機能開発プロジェクトが優先される ロードマップとして公開されている機能もある 優先度が高いプロジェクトの作業が差し込まれ、 Swift化の開発スピードが低下する
2. ASTプロジェクトの難易度の高さ
ASTプロジェクトとは? 52 抽象構文木(英: abstract syntax tree) 言語などの論理構造を表した木構造のデータのこと AST プロジェクトとは? AST
「Chatwork」のメッセージ記法は、長年各クライアントで 独自の解釈がおこなわれており、タグによっては見た目が異 なるという問題が発生していた この問題を解消するためのプロジェクトで、メッセージ記法 解釈と描画の共通化を目指した
Swift化とASTプロジェクトが並走すると… 53 ASTプロジェクトの優先度が高かったため、 一定の人員リソースが確保される ASTプロジェクトは難易度が高いため、この状態が1年半続いた Swift化に開発メンバーをアサインすることができず、 Swift化の開発スピードが低下する iOSアプリはメッセージ入力欄が WYSIWYGに対 応しているため、他のプラットフォームと比較して
開発範囲が広かったことも影響
3. Objective-CとSwiftが混在している
Objective-CとSwiftが混在している 55 Objective-C内でもSwiftのコードを呼び出す可能 性があるため、Swiftらしい書き方ができない • NSObjectを継承する必要がある • enum: Intしか使えない ◦
enum: String使えない • structが使えない ◦ すべてclassでかく必要がある • @objcを付ける必要がある 例えば... 技術的負債
4. 開発メンバーの設計思想の違い
Swift化開始時にある程度ルールは決めた 57 大まかな設計、実装方針は開発メンバーで認識を合わ せていた 設計漏れの部分や細かい実装方針については個々で考 えて実装され、開発メンバー内にあまり共有されてい なかった 実装が統一されずに、技術的負債となる
58 現在のiOS版アプリ 5
現在のiOSアプリ 59 • 95%程度がUIKit ◦ 新画面ではSwiftUIを積極的に使っている • MVVMからSVVSというアーキテクチャへ移行中 ◦ SVVSはオリジナルのアーキテクチャ
◦ SwiftUI化も進めている ◦ 実装ガイドラインを策定し、ルールについての認 識をiOS開発チーム内で行っている • BitriseからXcode Cloudへの移行を進めている 技術観点
現在のiOSアプリ開発のチーム体制 60 • 開発基盤を整えるチームと、機能開発を行うチームを分けた ◦ SVVS化の開発スピードを上げられる体制づくり iOS 価値 価値 Android
機能開発チーム 開発基盤を整えるチーム 機能開発を行うチーム 機能開発チーム サービス利用者
現在のiOS版アプリ開発のチーム体制 61 • この体制で開発を進めているが、まだまだ課題がある ◦ 両チームの責任範囲がきちんと分けられておらず、ボールが チーム間に落ちることがある ▪ 運用保守 ▪
サポート対応 ◦ モジュール単位で機能チームが分割されておらず、自己管理さ れたチームづくりが難しい ▪ チーム間で密なコラボレーションが必要になり、認知負荷が 向上する
働くをもっと楽しく、創造的に