mikan iOS 2024年の技術的構成について
これはmikan Advent Calendar 2024 23日目の記事です。
22日目は@mikan__chiakiによるテスト観点リストでテスト分析を効率化した話でした!mikanのQAクオリティはものすごく、個人的にも何度も助けられています。
はじめに
2022年に以下のような技術構成や開発体制についてのまとめを投稿しました。
当時から約2年経過して環境やプロジェクト構成も様変わりしてきましたので、年末の振り返りも兼ねてここにまとめさせてもらおうかと思います。
開発体制
当時は2名で開発してきましたが今はメンバーが倍ぐらいに増えました!相変わらずゆるめアジャイルで開発しています。
当時と大きく変わっているのはLinearの導入です。
Lienarの紹介は別のポストで紹介しているので詳細は省きますが、個人的にLinearが提唱しているLinear Methodという開発哲学をめちゃくちゃ気に入っています。賛否両論もあり、強めの言葉で語られていますが、アジャイルのエッセンスを取り入れつつモダンな開発チームにフィットしているものではないかなと思います。
ユーザをLinearというサービスはそのLinear Methodを色濃く反映しつつ、いわゆるアジャイル開発でも柔軟に使えるような設計となっているところがとても開発者ファーストなツールとして機能しています。とにかくおすすめです!
iOSチームも1週間1サイクル(スプリント)として実装を進めています。
8:2で開発効率化
開発チーム編成を職能別に変えてみたらチームの強さを感じた|satoshin21
こちらで去年書いたのですが、毎スプリント8割を施策の開発、2割で開発改善系のタスクで割り当てて毎サイクル少しずつ開発系の改善にも着手できています。後述しますがダークモードの対応やSwift6への移行、UIKitからSwiftUIへの移行もこの2割で少しずつ対応できるリズムができてきました。
よく面談などで「施策に押されて破綻しませんか?」と聞かれます。確かにQAが立て込んだ時などおおよそ全体のサイクルの1割ぐらいは開発効率化系のタスクに取りかかれない時もあるのですが、ほぼほぼ8:2のリズムで改善系を進めています。
今まで施策開発に押され開発効率化タスクなどに取り掛かれなくなってしまう、ということがよくあったのですがそれなりにうまくいっているのは要因として二つあるかなと思います。
一つは最終的なサイクルプランニングの意思決定権が基本的にiOSチーム、自分たちにあるところです。一つのバックログ上で優先順位を決めて上から取っていくということになると開発効率化系のタスクはなかなか優先順位は上がりません。そこでiOSチームで管理する開発効率化のバックログを別で作り、各チームが合意を取った上で8:2の割合でそれぞれのバックログからとって取り掛かっていくようにできています。これは今のメンバーが「施策開発も開発効率化もどちらもプロダクト改善において必要なタスク」と考えることができるバランス感覚の良いメンバーが集まっているからできることなのかなとも思います。
もう一つはその開発効率化バックログで実施しているサイドプロジェクトの効果が見えてきているためです。ダークモードもこの開発バックログに入っていて、通常のバックログでは優先順位が上がりづらいけどユーザに求められているものもiOSチームの判断で開発を進められており、またそれがユーザに受け入れられているためiOSチーム以外でも上記開発効率化バックログについての良さを受け入れられているのかなと思います。
プロジェクト構成
現在のプロジェクト構成も振り返ってみると当時から大きく変わらず運用できています。SwiftPMでモジュール分割を実施しており、大きくFeatureとUseCaseなどのビジネスロジックを分離し、一方向の管理体制とすることでテスト開発がしやすくPreviewを活用した開発・確認の改善サイクルを高速にまとめることができます。
現在確認したところモジュールが100近く存在していました。結構多い!こういう細かいモジュールの管理が可能になったのもSwiftPMのおかげかなと思います
SwiftUI
引き続きUIKitで実装されているコードは多くありますが、今年に入ってようやくアプリのエントリーポイントをAppDelegateからSwiftUI.Appに移行することができ、起動時のルーティングからメインの学習導線に至るまでプロダクトのコアとなる部分に関しては全てSwiftUIで開発するようになりました。
今後もできるところはSwiftUI化を進めていき、ピュアSwiftUIなアプリを作っていきたいと考えています。
Swift6
Swift6については現在はおおよそ対応状況20%ぐらいの対応率となっています。上記Swift Package Managerで対応を進めているため、各モジュールごとに少しずつ対応していっています。
Package.swift内部で以下のような形でwarningメッセージを表示し対応・未対応の進捗を管理しています。
extension SwiftSetting {
@available(*, deprecated, message: "Strict Concurrency Checking")
static let legacyLanguageMode: Self = .swiftLanguageMode(.v5)
}
let package = Package(
name: "Mikan",
...
targets: [
.target(
name: "Repository",
dependencies: [
"GraphQL",
],
swiftSettings: [.legacyLanguageMode]
),
利用できるところからSwift6を使っていますがとにかくtyped throwsが最高ですね!エラーの型化がはっきりできるのでより明示的且つ簡潔なインターフェース設計が可能になるので活用していきたいです。またStrict Concurrency Checkingに対応することによる恩恵が非常に大きいので、開発効率化タスクとして積極的に取り組んでいきたいと考えています。できれば今年度中には終わらせたい・・・。
当たり前クオリティに向けて
当時当たり前クオリティとして上げていた機能についても多く対応することができました。
ダークモードはユーザからの要望も多く、サブプロジェクトとして実装を進めておりました。仮説検証という形ではなく、上記で紹介した8:2のうちの2、開発効率化の文脈で実装を進め、デザイナーチームなど各チームの協力もあり無事に今季の頭にリリースすることができました。
またiPadのSplit ViewをはじめとしたiPadに合わせた体験の改善についても少しずつ進めています。ユーザの割合的にもなかなか優先順位があがりにくい部分ではありますが、iPadを学習に利用しているユーザはとても多く、またマルチタスキング前提の設計となっているiPadをiPhoneなどの携帯端末とは別の体験を突き詰めるため引き続き改善を進めています。まだ最適な体験とは言い難いですが、今後もiPadならではの学習体験を提供できるように改善を進めていきます。
まとめ
2年前から変わっていないところや大きく変わっていることもあり、アドベントカレンダーをきっかけに改めて現状について見つめ直すことができました。
今後もよりよいサービスを提供できるよう、iOSエンジニアという観点から開発を進めていきます!よろしくお願いします。
Discussion