mobileツイートminne事業部モバイルチームのエンジニアをしております、@umatoshiです。最近はパルワールドに夢中で、全力で配合に取り組んでいます。好きなパッシブスキルは脳筋です。現在私は、minneのiOSアプリを開発しており、最新バージョンのXcode(執筆時点では15.2)対応とiOS15サポート終了予定等、2021年当時の記事からアップデートしたので、採用している新技術や開発効率を上げるための工夫をはじめとしたトピックを、minneのiOSチームに興味がある方へ向けて共有したいと思います。2023でブース出展もしていて、弊社から登壇もしていてminneについて紹介しています。Concurrencyなど、チームで多くの面白い新技術を活用して開発効率を上げています。通じて、コード生成AIを最大限に活用しています。Copilotの導入によってペパボの開発生産性はどう変化したのかをご参照ください。ここからはより詳しい内容を説明します。iOSアプリの歴史と概要まず、minneのiOSアプリは2012年から開発が始まって10年以上の歴史があります。当時は全てObjective-Cで書かれていましたが、現在ではソースコードの99%以上がSwiftに移行できています。現在ではObjective-Cを触る機会は滅多にありません。Swift化を目指しています。アーキテクチャーは、MVVM+Rを採用しており、今後はSwiftUIがメインになる事を考慮した形にしています。ビルドは最新Xcode上でビルドできるようにしていてプロジェクトはXcodeGenを使用し、CocoaPodsとSPMの両方を使ってサードパーティ製のライブラリを導入しています。基本的にはSPMを推奨していますが、止むを得ない場合はCocoaPodsを使用していいます。CocoaPodsについては徐々にその割合を減らし、今年中にCocoaPodsを止める予定で進めています。ビルドやデバッグに関する処理については、できるだけfastlaneで完結する方針を取っています。BitriseをはじめとするCIサービス設定を少なくする事でサービスへの依存度を下げ、容易に手元での検証ができる体制を作っています。開発体制minneは、iOSエンジニア3名で開発しており、デザイナー、ディレクター、ほかのエンジニアと協力して、機能追加と保守を行っています。Meetで行っています。2週間ごとのサイクルでアプリをリリースする計画を立てています。隔週でminne事業部の目標達成に向けた中期的な(半年〜1年先の)モバイルアプリ戦略の会議を、iOS・Androidのチーム合同で開催しています。会議では課題の共有やリスクの低減、進捗状況の確認を行っています。チームの特徴としては毎朝同期的なレビューする時間をもうけてコミュニケーションをとって「速(そく)」を出しています。Siliconが載った高性能なMacBookも支給されています。36GBに乗り換え予定です。Enterpriseです。ビルドは最新Xcode上でビルドできるようにしていてプロジェクトはXcodeGenを使用し、CocoaPodsとSPMの両方を使ってサードパーティ製のライブラリを導入しています。Xcode上でコード生成AIをフル活用しています。SwiftコーディングガイドとしてはSwiftLintとSwiftFormatを使用しており、gitコミット時に差分ファイルのみ実行するような工夫を入れています。GPT-4を活用した内製AIコードレビューツールを導入しました。これにより、コードの差分を分析し、要約やリファクタリングの提案をAIが自動で行います。このような仕組みを導入することでレビュー時には人間が本当に必要なところを集中的にレビューすることができています。開発言語と主要フレームワーク99%以上Swiftです。新規のものは必ずSwiftで開発していて、残っているObjective-Cは少しずつ減らしています。betaへの対応も確認できています。15のサポートを終了する事もあり、現在も継続してiOS16以降を見据え、SwiftUIでの実装がしやすくなる環境を整備しています。来る想定なのでいち早く対応できるように取り組んでいます。UIについてですが、ほぼUIKitの実装が多いですが新規画面はSwiftUIを採用していて、UIKitからSwiftUIに置き換えて行っています。UiKitの画面が多いのでSwiftUIにたくさん移行していきたいです。UIKitはモダンなAPIを使うように心がけており、例えば、UICollectionViewを使っている新規画面でだいたいDiffableDataSourcesとCompositionalLayoutを使っています。FirebaseやReproをPuree-Swiftでラップし、統一されたインターフェースを実現しています。ViewController」様な形のアーキテクチャとなっていました。Presenter(MVP)を採用しました。画面遷移やモデル層のアーキテクチャに関しては、明確な方針が定められていませんでした。2019年にSwiftUIとCombineが発表され、また、minneが90%以上Swift製になりました。Programming(FRP)的なアプローチが求められ、MVPのままだと、SwiftUIへ移行しにくいのでは?という疑問がありました。ViewControllerをMVVMにすることが決まりました。(MVPになっている画面はいったんそのまま)そのあと、2020年から画面遷移やモデル層の設計決めを本格化し、モデル層について議論してきました。Fluxをそれぞれ比較して、TCAをいくつかの画面で実際に試し、導入した場合を検証しました。実際TCAをプロダクションに使ってみて、他の設計と比較しました。ほかの設計とは、MVVMのGUI設計に、モデル層の定義してみたアーキテクチャのことです。Repository層というアーキテクチャに決まりました。AppEnvironmentが膨大になってしまう可能性があるフレームワークを使うことになるので、TCAの実装の細部まで知る必要があるテストやビューコード、ビジネスロジックがかなり外部ライブラリに依存してしまう一気にTCAに乗り換えることができず、MVP/MVVM/TCA混在になる併用期間が長そう画面間の情報共有はまだ考えることがある現在採用しているアーキテクチャに関する詳細はこちらでも紹介しています。過去にminneではRxSwiftを使用していましたが、完全に取り除きました。その代わりにAppleが提供しているCombineを利用してFRPの実装を書いています。SwiftUIとCombineの親和性が高いので、SwiftUI時代を見据えて少しずつ移行をしています。Concurrency対応などを徐々に進めています。APIの通信部分にはAlamofireをやめて通信ライブラリや通信のモックライブラリ(OHTTPStubsなど)を一切使っていません。代わりにFoundationの素のURLSessionをラップしたAPIクライアントを実装しています。レイヤーが減るので、デバッグもしやすくなる、アップデート対応がなくなる、依存性が減るのような理由からです。APIからGraphQLに移行しているので、その辺りの通信処理を一部apollo-iosに託しています。APIクライアント・GraphQLクライアントを意識せずに呼び出す事を可能にするネットワークレイヤーを設計しています。マッピングはデータ取得時にGraphQLのEntityからアプリ内部で利用している既存Entityへ変換して利用しています。Rails経験者が多い事もあり、RSpecに近く易しい書き方が可能なQuickとNimbleを利用しています。Injectionをする方針を取っています。Mockは型付けの強いSwiftでは作るのが面倒ですが、SourceryのAutoMockableテンプレートを活用して、Protocolから生成しています。CombineのコードはXCTestExpectationだけでは、以下の問題があるので、CombineExpectationsとCombineSchedulersを使ってテストを書いています。TestFlightを使っています。Actionsについてもスペルチェックやラベル付け等といった補助的な形で利用しています。方針として、できるだけ多くのことを自動化することによって、開発とレビューに割ける時間を最大化し、アウトプットの量を増やし品質を向上できると考えています。Fastlaneはもやはモバイル開発の定番の自動化ツールで、スクリーンショット作成以外は、メインのアクションをすべて活用しています。GPT4を利用した内製AIコードレビューのツールを導入しています。私ごとですが優秀でかなりおすすめです。ViewControllerが残っている状態です。ViewControllerの画面をSwiftUI+MVVM+RもしくはUIKit+MVVM+Rへの書き換えに積極的に取り組んでいますが、まだまだ追いついていないのが現状です。Proで気にならないぐらいには解決していますがメインバンドルが大きいのでSwiftUIのプレビューが動かないなど改善が必要です。APIからGraphQLへ全面移行など課題がいっぱいあります。iOSアプリでの開発状況です。質問や疑問などあれば、ぜひカジュアル面談にお申し込みくださいませ〜。