NEWSニュース

2020.04.27

TECH BLOG

最近のiOSの開発環境の話

こんにちは、ネイティブチームの坂上です。

iOSを専門にコードを書いたり、社内勉強会の主催をしたり、最近までは若手エンジニア、デザイナー主体の活性化組織であるCreativeNextとしても活動していました。記事はこちらをご覧ください😎

今回は、半年前にリニューアルしたとある占いアプリと、現在もアップデートを続け定期的にアップデートを行なっている社内のアプリ開発環境の向上についてお話します。

 

目次

    1. – ツール
    1. – CI/CD
    1. – モデル生成

 

アーキテクチャ

当時の開発については僕がまだ入社してなかったため全容は把握していないですが、オーソドックスなMVC設計でした。

ただ、これを機にアーキテクチャを刷新することにしました。

アプリの仕様上、状態管理が多いことと画面にすぐに反映する必要があることから、データバインディングと親和性を感じ MVVM を採用しました。また、以前社内で開発していたアプリは MVVM を採用しており、また僕も経験があることも理由の一つです。

これにより、ViewControllerからプレゼンテーションロジックを排除し、 ViewModel に分離することができました。データ層へのアクセスはリポジトリパターンを採用し、Database, API どちらからアクセスするかを隠蔽し、ViewModel はシンプルにアクセスするだけにしました。

 

ツール

開発周辺ツールにおいても、昨今のiOS開発でのトレンドと実績を加味して以下を採用しました。

 

 ●Carthage

 ●fastlane

 ●Mint

 ●SwiftLint

 ●SwiftFormat

 ●SwiftGen

 ●XcodeGen

 

iOSのコソコソ噂話になりますが……

 

iOS開発で何より辛いのは、 複数人開発における project.pbxproj のコンフリクトです。正直、何回も直していると慣れてきてわかってしまうのですが、この作業は骨が折れる上直してる時間も無駄に思えて仕方ない気持ちになります。パズルをしている感覚に近いです。間違った場合は

 

Xcode 「このプロジェクト開いたけど構造がおかしいから見えないよ😉」

 

としか言ってくれません。辛い……😇

そこで活躍するのが、 XcodeGen です。

 

XcodeGen

https://github.com/yonaskolb/XcodeGen

XcodeGen は、 以下のように yaml を書くことで xcodeproj を自動生成するツールです。

 

これにより、 project.pbxproj で定義したファイル構造と実際のファイル構造が必ず同じものが作られるようになりました。その他、様々なメリットもあります。

 

 ●ライブラリを定義でき、依存性が明確になる

  ・Carthage の場合 Run Script も自動更新してくれる

 ●Config の追加が容易(あとから QA 環境つくれって言われたときとか)

 ●後からモジュール分割・統合が容易

 ●Macのパスに合うためGitHubから見たフォルダ構造と乖離がない

 ●xcodeprojを生成しているだけだから必要なくなったら捨てられる

 

CI/CD

運用開始から長いサービスで、CIは導入されておらず開発者のMacでビルドする形が残っていました。

しかし、このプロジェクトが始まったタイミングで、ちょうど社内のCI環境をオンプレミスの Jenkins から Bitrise に移行しようという話が出たため、この流れに乗って Bitrise 上で構築することにしました。

また、社内のアプリケーションはすべて Bitrise に移行しています。

https://www.bitrise.io/

 

各種自動化したので一部紹介します。

 

Firebase App Distribution 配布

development / staging 環境のテスト配布は、 Firebase App Distribution を使っています。

最近Bitrise側が公式にStepを追加したため、容易に配布が可能となりました。

現在はトリガーを使っておらず、必要に応じてポチってます。

 

Carthage/Cocoapods ライブラリの更新情報

一度ライブラリを導入した途端、更新しないあるある。セキュリティから見ても放置するのは良くないです。

Bitrise の script を実行する Step を使って更新情報を取得し、Slack に吐き出しています。毎週の決まったタイミングで決まったチャンネルに流すようにしています。

 

こんな風に出ます。↓

 

PR 時の自動コメント

一々指摘するのが面倒なこと、例えば コード規約に沿ってないことをわざわざコメントで書くのは無駄です。そのため、Danger を用いて自動化しました。

※ブログ用にコードを改変してます

 

AppStore へバイナリアップロード

アプリ申請処理時に、 AppStore へアーカイブしたバイナリーを送ります。その際、開発者が必ず行う CFBundleShortVersionString / CFBundleVersion の更新も行っています。  

具体的には、以下の2つをStepとして定義しています。

 

●バージョンを更新してリリース用 PR を出す Step

●リリース用の PR が作成された事を Hook して ビルド・アップロードをする Step

 

また、 Bitrise 上のワークフローを Slack 上で実行できるよう Slack Bot を追加したため、わざわざ Bitrise のサイトを開かずともできるようになりました。

 

モデル生成

最後に、モデル周りの話をします。

CAM ではAPI定義に OpenAPI を積極的に利用しています。

https://www.openapis.org/

 

OpenAPI の記述を元に、iOS では openapi-generator を用いてコード生成を行っていますが、その具体的な方法をご紹介します。

https://github.com/OpenAPITools/openapi-generator

 

構成

 

まず API定義している yml ファイルを 特定のリポジトリ(仮に xxx-oas とします)で保管します。

xxx-oas に commit が push されたことを Hook して、 サーバ上でコード生成してそれを保管するリポジトリ(仮に xxx-ios-api-gen とします)に push するスクリプトを走らせます。

下がサンプルコードです(一部編集しています)。

 

これで xxx-ios-api-gen を Carthage, Cocoapods, Swift Package Manager なりを用いて取得すれば良いのですが、一点注意があります。それは Carthage を利用する場合、 xcodeproj を都度更新する必要があるということです。

 

Carthage は xcodeproj で管理されているswiftファイルをビルドするため、新規に生成したファイルだったり、削除したファイル分を更新しないと使えません。

以前はこれを手動で行っていましたが、今は XcodeGen の project.yml を一緒に吐き出してくれるおかげで自動化が可能になりました。

現在は xxx-ios-api-gen の push を Hook して、 Bitrise 上から XcodeGen で xcodeproj を生成してコミット・タグ付けを行っています。

 

まとめ

地味だけど必須な作業を自動化することで、開発者がコードを書くことに集中できるようになりました。色々と説明しましたが、これを全社のアプリで行っています。  

 

これは、小さな事、大きな事でもフレキシブルにやっていける今の体制のおかげでもあります。

まだまだ足りない事も沢山ありますが、どんどん改善していけるよう頑張ります💪

 


 


WRITTEN BY:坂上
2017年新卒のiOSエンジニア。社内の iOS 周り開発・CI導入など色々とやってます。