iOSプロジェクトのベストプラクティスとツール

オープンソースのXcodeプロジェクトテンプレートを使用

グリーンフィールドiOSプロジェクトで作業するとき、私はしばしば新しいプロジェクトをゼロから開始しなければなりませんでした。その間、私と私のチームは、ツールの統合、プロジェクト構造の設定、基本クラスの作成、外部ライブラリの統合など、基本的なプロジェクトの設定に常に多くの時間を費やしていました。

プロジェクトのスタートアップに費やす時間を節約し、プロセスをほぼ自動化できると判断しました。私が使用した通常のベストプラクティスとツールをすべて書き留め、新しいプロジェクトを開始するときに自分とチームが使用できるプロジェクトテンプレートを準備しました。このテンプレートは、プロジェクトのセットアップ時間を節約し、各チームメンバーが慣れ親しんでいる共通の基盤を提供するので、プロジェクトの構造と基盤を考えて検討する必要がありません。それらは常に同じです。

テンプレートに含まれるすべてのツールまたはベストプラクティスは、それ自体で記事に値しますが、各ポイントをまとめて、それらを含めた理由を簡単に説明したいと思いました。

ココアポッド

これは紹介する必要はないと思います。これは、iOSプロジェクトの外部依存関係を管理するためのライブラリです。それは長い間存在しており、堅牢であり、数百(数百万ではないにしても)のプロジェクトでテストされています。 Carthageのような代替の依存関係マネージャーがありますが、Cocoapodsがサポートするオープンソースプロジェクトの範囲が最も広いため、Cocoapodsを使用することにしました。 Cocoapodsの使用は非常に簡単で、必要なパッケージを簡単に見つけることができる検索インデックスが付属しています。

テンプレートプロジェクトには、SwiftlintとR.swiftを含む単純なPodfileが付属しています。テンプレートには、依存関係を解決するために使用されるCocoapodsバージョンを管理するためのGemfileも含まれています。これは見過ごされがちな改善であり、チームの開発者がCocoapods自体の異なるバージョンを使用して依存関係をインストールするときに発生する問題を防ぎます。 Gemfileは、チーム全体で同じCocoapodsバージョンの使用を強制します。

スウィフトリント

Swiftlintは、チームのすべてのプログラマーに特定のルールとコーディングスタイルを適用するための非常に便利なツールです。強制的なアンラップ、強制的なキャスト、強制的な試行などの危険なことについてプログラマーに警告する自動コードレビューシステムと考えることができますが、すべてのプログラマーが同じ「コードスタイル」関連ルールに従うようにすることで、共通のコーディングスタイルを実施しますインデントまたはスペースルールのような。これには、これらの基本的なチェックを行うことでコードレビューの時間を節約するだけでなく、プロジェクト内のすべてのファイルが見やすくなり、読みやすさが向上し、その結果、すべての開発者が理解できるという大きな利点があります。ここですべてのルールのリストを見つけることができます。テンプレートでは、SwiftlintはCocoapodsを介してインストールされ、Build Phasesステップに含まれているため、プロジェクトのビルドごとに開発者に警告を発し、警告します。

R.スウィフト

R.swiftは、画像、フォントセグエ、ローカリゼーションなど、強く型付けされたオートコンプリートリソースを取得するためのツールです。これは、プロジェクトをスキャンし、リソースを取得するために必要な迅速なクラスを生成することによりこれを行います。このライブラリの最大のセールスポイントは、リソースを使用しながらコードを作成できることです。

  • 完全に型付け—メソッドが返すものをキャストおよび推測する必要が少なくなります
  • コンパイル時のチェック-実行時にアプリがクラッシュするような間違った文字列はもうありません
  • オートコンプリート-その画像/ペン先/ストーリーボード名を再度推測する必要はありません

公式の文字列APIを使用した次のコードを検討してください。

let icon = UIImage(named:“ custom-icon”)

イメージ名のスペルを間違えた場合、ここでnilが表示されます。チームのメンバーが画像リソースの名前を変更した場合、このコードはnilを返すか、画像を強制的に展開するとクラッシュします。 R.swiftを使用する場合、これは次のようになります。

let icon = R.image.customIcon()

これで、アイコンが実際に存在することを確認できるようになり(コンパイル時のチェックのおかげでコンパイラーが警告を表示します)、オートコンプリートを使用するため、アイコン名にタイプミスをしないことがわかります。

R.swiftはCocoapodsを介してインストールされ、ビルドフェーズとしてテンプレートに統合され、各ビルドでSwiftラッパークラスを生成します。つまり、file / image / localization / font / color / nibなどを追加すると、プロジェクトのコンパイル後にR.swiftを使用して使用できるようになります。

テスト用に個別のAppDelegate

よく見落とされがちな良い習慣は、テストを実行するときに別のTestAppDelegateクラスを持つことです。なぜそれが良いアイデアですか?通常、AppDelegateクラスはアプリの起動時に多くの作業を行います。ウィンドウのセットアップ、アプリの基本的なUI構造の構築、通知の登録、データベースのセットアップ、さらにはバックエンドサービスへのAPI呼び出しを行うこともできます。単体テストには副作用はありません。いくつかの単体テストを実行するためだけに、ランダムなAPI呼び出しを行い、アプリのすべてのUI構造をセットアップしたくないですか?

TestAppDelegateは、テストスイートの実行中に1回だけ実行するコードを保持するのにも最適な場所です。モックを生成するコード、ネットワーク要求をスタブするコードなどを含めることができます。

テンプレートには、アプリのメインエントリポイントであるmain.swiftファイルが含まれています。このファイルには、アプリが現在実行している環境を確認するメソッドがあり、テスト環境の場合はTestAppDelegateを呼び出します。

コンパイラパフォーマンスプロファイリングフラグ

Swiftはすばらしい言語であり、Objective-C(IMO)よりも使いやすく、はるかに安全です。しかし、最初に導入されたときは、1つの大きな欠点がありました-コンパイル時間。 Swiftの2日間に戻って、私は大まかに4万行のSwiftコードを持つプロジェクト(中規模のプロジェクト)に取り組んでいました。コードはジェネリックと型推論を使用して非常に重く、クリーンビルドをコンパイルするのに5分近くかかりました。小さな変更を加えても、プロジェクトは再コンパイルされ、変更を確認するのに約2分かかりました。これは私がこれまでに経験した最悪の開発者体験の1つであり、そのためにSwiftの使用をほぼやめました。

当時の唯一の解決策は、プロジェクトのコンパイル時間をプロファイルして、コンパイラを高速化するような方法でコードを変更しようとすることでした。これを支援するために、Appleは、メソッド本体のコンパイルや式のタイプの解決に時間がかかりすぎた場合に警告する非公式のコンパイラフラグをいくつか導入しています。これらのフラグをテンプレートプロジェクトに追加したので、最初からアプリの長いコンパイル時間について警告されます。

現在、ビルド時間は劇的に改善されており、ビルド時間を改善するためだけにコードを微調整する必要はほとんどありません。ただし、プロジェクトが大きくなりすぎた場合は、事前に問題を解決してから問題を解決することをお勧めします。

開発/ステージング/本番構成

もう1つの優れたプラクティス(または必要と言えるかもしれません)は、開発環境、ステージング環境、および実稼働環境に個別の構成と環境変数を設定することです。現在、ほとんどすべてのアプリは何らかのバックエンドサービスに接続する必要があり、通常、これらのサービスは複数の環境に展開されています。開発環境は、日々の展開と開発者がコードをテストするために使用されます。ステージング環境は、テスターとクライアントがテストする安定したリリースに使用されます。本番環境の目的は誰でも知っています。

iOSプロジェクトで複数の環境をサポートする1​​つの方法は、プロジェクトレベルの構成を追加することです。

プロジェクトレベルの構成

構成を定義したら、各環境の変数を含むConfiguration.plistファイルを作成できます。

Configuration.plist

プロジェクトの実行時に、使用する構成を指定できます。これは、ビルドスキームで実行できます。

次に、プロジェクトのInfo.plistファイルに1つのプロパティを追加する必要があります。このプロパティの値は、実行時に現在の構成の名前に動的に解決されます。

これはすべて、テンプレートで事前に構成されています。

残っているのは、ビルドスキームで選択した構成に応じて、実行時にこれらの変数を取得できるクラスを記述することです。テンプレートには、現在の環境の変数を取得できるConfigurationManagerクラスが含まれています。 Githubでそのクラスの実装を確認して、その動作を確認できます。

Readme

すべてのプロジェクトには、少なくとも依存関係をインストールしてプロジェクトを実行する方法が記載された基本的なReadmeが必要です。また、プロジェクトのアーキテクチャとモジュールの説明も含める必要があります。残念ながら、開発者はドキュメントを書くのが好きではありません(readmeはその一部です)。私は数か月間開発されていたプロジェクトを見てきましたが、基本的なReadmeもありました。この基本的なREADMEを作成する負担を取り除くために、テンプレートにはインストールとプロジェクト構造をカバーする標準のREADMEが含まれています。テンプレートを使用して新しいプロジェクトをセットアップすると、Readmeが自動的に含まれます。

ジギニョレ

現在、ほとんどのプロジェクトはバージョン管理システムとしてGITを使用しています。 GITを使用する場合、通常、プロジェクト内のビルドフォルダーや派生データフォルダーなどの一部のファイルまたはフォルダーを無視する必要はありません。 iOSプロジェクトに合ったgitignoreファイルを検索する手間を省くために、テンプレートにはGithubコントリビューターが提供する標準のgitignoreが含まれています。

ディープリンクと通知を処理するための基本クラス

最近のほとんどすべてのアプリは、ディープリンクと通知を処理する必要があります。これを行うには、開発者はAppDelegateクラスにある程度の定型コードを記述する必要があります。テンプレートにはカバーされているものがあり、ディープリンクと通知の操作を簡単にする基本クラスも提供します。

概要

要約すると、テンプレートはベストプラクティスを含めようとし、有用なサードパーティツールを統合します。これにより、新しいプロジェクトのセットアップに費やす時間を節約でき、プロジェクトの残りの部分に共通で強力な基盤を提供できます。よろしくお願いします!

PS:テンプレートの問題や機能のリクエストがある場合は、Githubに問題を残してください。暇なときに解決しようとします。