iOS開発(Swift)のおすすめ構成〜実践編〜

botman_blue iOS

はじめに

ライブラリ編の続きです。
おすすめ構成を実践してみました。今回アーキテクチャに関しては特に触れないですがプレゼンテーションロジックをどっかに置きたいと思い PresentationModel というよくわからないものを置いています。

ソースはココ (github)

つくったアプリ

つくったのは3画面程度の小さなアプリでランダムにどっかの都道府県の今日の天気を教えてくれるアプリです。
よくわからないアバター表示と履歴に保存する機能があります。

スタート お天気 履歴(あり) 履歴(なし)
start weather history no_history

下記 API を利用

フォルダ構成

フォルダ構成はこんな感じ。Source と Resourece で分けて最初からある AppDelegate とかは Sourece 直下に置き、他は Screens (画面)と PresentationModels (プレゼンテーション層?っぽいやつ)に分けています。

directory

モデル部分は別モジュールに分割しています。今回は Models でまとめていますが適切な粒度でさらに分割してもいいと思います。(ビルド時間の短縮は重要!!)

モジュール作成方法は下記のように File -> New -> Target -> Framework でできます。

target
framework

画面構成

画面構成は Storyboard を使うのか xib を使うのか全部コードでやるのかとプロジェクトごとに色々あると思いますが私のおすすめは1画面1 Storyboard です。以前記事書いたのでよかったらどうぞ(storyboard とのつきあい方
Storyboard だと SegueContainer View が使えるので xib ではなく Storyboard を使っています。Segue がいいのかは好みが分かれると思いますが Unwind Segue とかたまに使いたくなるので私はわりと Segue を使っています。画面間は Storyboard Reference でつないでいます。

こんな感じ

storyboard

ついでにアプリの rootViewController に関しても少し。アプリ起動時の画面を条件によって変えたい場合がたまにあると思いますが、そういう場合 AppDelegatewindow.rootViewController を差し替えたりしてたのですがこの方法あまり良くないなと思い今回のやつは Main.storyboard と ViewController.swift を残して下記のように ViewControllerchildViewController で初期画面を設定しています。これで常にエントリポイントは ViewController になるんでいいんじゃないかなと思いますがこれでやったことないので要検討です。(もしかしたらなんか弊害あるかも??)

使用ライブラリ

ライブラリ 用途
mac-cain13/R.swift リソース管理用
realm/SwiftLint Lint ツール
mono0926/LicensePlist ライセンス表記用(ライセンス表記は大事😇)
ishkawa/DIKit DI 用
realm/realm-cocoa DB
ishkawa/APIKit 通信用
SwiftyBeaver/SwiftyBeaver ログ出力用
Quick/Quick テスト用
Quick/Nimble テスト用

ライブラリ編 で記載したように Carthage -> SPM -> Pods の順で導入しました。R.swift, SwiftLint, LicensePlist を Pods で導入し残りは Carthage で導入しました。今回 SPM の出番はなかったです。。。SVG 表示用に mchoe/SwiftSVG を SPM で入れようかと思ったのですが今回の SVG 表示には対応してないみたいであきらめました。。。(WKWebView で表示してます)

cocoapods のバージョンを開発者間で揃えるため bundler を使ってます。(パッケージマネージャ編参考

APIKit を閉じ込めたいと思って色々やってたら通信周りはほぼ自作になってしまいました。。。(HTTP ステータスの判定部分はもうちょい工夫がいる気がする)

Xcodeのバージョンをそろえる

開発者間で Xcode のバージョンが違うとたまに思わぬ弊害があるので Run Script を追加してバージョンが違えばエラーを出すようにしました。

参考:Xcodeバージョンをビルド時に厳密にチェックする

方法

  1. プロジェクトのトップディレクトリに .xcode-version ファイルを追加
  2. Run Script を追加

.xcode-version

Run Script

これで Xcode 11.5 以外でビルドするとエラーになります。
ライブラリとか色々スクリプト追加すると今回のやつはこんな感じになりました。

script

スキーム

アプリ開発をする際は本番用サーバと開発用サーバなどサーバのつなぎ先を変えたりといったことがよくあります。そういう時のためにそれぞれスキームを追加します。やり方は以前書いたこの記事参考(Xcodeで本番アプリと開発アプリをわけるベストプラクティス

  1. Project -> Info -> Configurations で Deug を複製する
    c_config
  2. 複製したConfigurationの名称を変更する(Debug copy -> Develop)
  3. Build Settings -> Swift Compiler - Custom Flags にフラグを追加する(開発なら DEVELOP ダミーなら DUMMY など)
    c_flag
  4. Build Settings -> Product Bundle Identifier で Bundele id を変更する
    c_id
  5. Build Settings -> Packaging -> Product Name でアプリ名を変更する
    c_product_name
  6. Build Settings -> Asset Catalog Compiler - Options -> Asset Catalog App Icon Set Name でアプリアイコンを変更する
    c_icon
  7. Manage Schemes... -> Duplicate でスキームを複製する
    c_scheme_dup
  8. スキームの名称を変更する(Copy of PiyoApp -> PiyoAppDev)
    c_scheme_name
  9. スキームの Build Configration を変更する(Run 以外の Test なども適宜変更する)
    c_scheme_bu
    c_scheme_build

コードで下記のように分岐させる。別モジュールだとこのフラグは有効ではないので注意が必要です。追加後に Pods でエラーが出る場合はもう一度 pod install する。おそらく Pods にも Configuration が自動で追加されるがその関連でエラーが出る。

今回のアプリは開発用サーバとかないので Dummy だけ追加してプロジェクト内のファイルを読みにいくようにしました。

おわりに

実際のプロジェクトだと fastlane とか jenkins とか設定すると思いますがその辺はいつも他のメンバがやってくれてたので私はわかんないです。。。(いつか覚えたい)
SwiftUI とかあるし今後はどんどん構成が変わっていくかもしれないです。今のとこ(2020/06/28)のあくまで個人的なおすすめ構成です。

あんま Coverage よくなかった。。。

coverage

コメント

タイトルとURLをコピーしました