前置き
Clean Architecture について
Architecuture の一つで詳細は下記の記事に載っています。
The Clean Architecture
それをiOS
開発に適用させるために参考になる記事を挙げます。
まだMVC,MVP,MVVMで消耗してるの? iOS Clean Architectureについて
iOS CleanArchitectureを使ってみた感想
これからクリーンアーキテクチャによるiOSアプリ開発をしようとしている人にオススメの4つの資料
本題
Clean Architecutre のデメリット
Clean Architecture
は各レイヤーごとに役割と責任を分離するために必然的にファイル数・コード量が多くなってしまうのが欠点として挙げられます。
コード量が多くなることで記述する時間・ファイルを作成する時間がその分割かれます。
その問題を解決するライブラリKuriを開発したのでご紹介します。
Kuri
KuriはiOS Clean Architecture用に開発したCLIツールです。
Kuriはコマンド一発で各レイヤーのコードを自動で生成してくれてかつXcode Project
にディレクトリ、ファイルをimport
してくれます。
さらにKuri には柔軟にジェネレートするディレクトリやプロジェクト、その内容を変更できる仕組みを設けています。
この記事ではその方法を説明していきます。
導入
まず導入の説明をします。
Kuriはgithub上に公開されています
そして一番新しくリリースされたバージョンのzipをダウンロードしてください。
https://github.com/bannzai/Kuri/releases
あとは展開したファイルをPATHが通っている場所に移動しましょう。
これでkuriコマンドをターミナル等のCLIで使う準備は終わりです。
setup
Kuriの機能を使うために準備するものがあります。
Kuri.yml
KuriTemplate
ディレクトリ
この二つがコードジェネレートするときに必要です。
これらを用意するコマンドがKuriには備わっています。
実際にプロジェクトがあるディレクトリに作業ディレクトリを移してください。
$ cd YourProject
$ ls
YourProject YourProject.xcodeproj YourProjectTests YourProjectUITests
環境によって異なりますが上記のようにls
をしたらYourProject.xcodeproj
があるディレクトリです。
作業ディレクトリを移動したらkuri setup
とコマンドを実行してください。
$ kuri setup
created Kuri.yml.
created template for Entity
created template for DataStore
created template for Repository
created template for UseCase
created template for Translator
created template for Model
created template for Presenter
created template for View
created template for Wireframe
created template for Builder
Successfully setup!
$ ls
Kuri.yml KuriTemplate, YourProject YourProject.xcodeproj YourProjectTests YourProjectUITests
以上でKuri.yml
とKuriTemplate
の作成が完了しました。
generate
さて本機能であるgenerate
コマンドについて見ていきます。
とりあえず実行してみましょう。
$ kuri generate Kuri
created: ./YourProject/Kuri/Entity/KuriEntity.swift
created: ./YourProject/Kuri/Entity/KuriEntityImpl.swift
created: ./YourProject/Kuri/DataStore/KuriDataStore.swift
created: ./YourProject/Kuri/DataStore/KuriDataStoreImpl.swift
created: ./YourProject/Kuri/Repository/KuriRepository.swift
created: ./YourProject/Kuri/Repository/KuriRepositoryImpl.swift
created: ./YourProject/Kuri/UseCase/KuriUseCase.swift
created: ./YourProject/Kuri/UseCase/KuriUseCaseImpl.swift
created: ./YourProject/Kuri/Translator/KuriTranslator.swift
created: ./YourProject/Kuri/Translator/KuriTranslatorImpl.swift
created: ./YourProject/Kuri/Model/KuriModel.swift
created: ./YourProject/Kuri/Model/KuriModelImpl.swift
created: ./YourProject/Kuri/Presenter/KuriPresenter.swift
created: ./YourProject/Kuri/Presenter/KuriPresenterImpl.swift
created: ./YourProject/Kuri/View/KuriViewController.swift
created: ./YourProject/Kuri/View/KuriViewControllerImpl.swift
created: ./YourProject/Kuri/Wireframe/KuriWireframe.swift
created: ./YourProject/Kuri/Wireframe/KuriWireframeImpl.swift
created: ./YourProject/Kuri/Builder/KuriBuilder.swift
created: ./YourProject/Kuri/Builder/KuriBuilderImpl.swift
write in project: YourProject.xcodeproj
なにやらいっぱい作られたみたいですね。
実際にXcodeを開いてファイルインスペクターを見るとKuri
ディレクトリができてその下にファイルができていると思います。
kuri generate XXX
でXXX
をprefixとしたファイルが一気にgenerate
され、
えさらにXcodeプロジェクトにimport
されていることが確認できたと思います。
これだけのファイルをコマンド一発で用意できるなんて便利ですね!
generate 応用
ここではKuriに用意されたgenerateコマンドの柔軟性について少し触れたいと思います。
まず前提としてsetup
コマンドで用意した二つのものの解説をします。
Kuri.ymlはgenerate
するための設定が記述されています。
具体的にはどのプロジェクトのどのターゲットをどのパスにファイルを作成するかを決めるための情報が記載されています。
KuriTemplateにはファイルをgenerate
するためのテンプレートがSwiftで書かれています。
今回はテンプレートの方に着目しましょう。
例えばKuriTemplate/Implement/Repository/Repository.swift
の定義はこうなっています。
//
// __REPOSITORY__Impl.swift
// Kuri
//
// Created by __USERNAME__ on __DATE__.
// Copyright © 2016年 __USERNAME__. All rights reserved.
//
struct __REPOSITORY__Impl: __REPOSITORY__ {
private let dataStore: __DATASTORE__
init(
dataStore: __DATASTORE__
) {
self.dataStore = dataStore
}
func fetch() throws -> __ENTITY__ {
return try dataStore.fetch()
}
}
これと先ほどgenerate
されたKuriDemo/Kuri/Repository/KuriRepositoryImpl.swift
と比較してみましょう。
//
// KuriRepositoryImpl.swift
// Kuri
//
// Created by kingkong999yhirose on 2016/12/25.
// Copyright © 2016年 kingkong999yhirose. All rights reserved.
//
struct KuriRepositoryImpl: KuriRepository {
private let dataStore: KuriDataStore
init(
dataStore: KuriDataStore
) {
self.dataStore = dataStore
}
func fetch() throws -> KuriEntity {
return try dataStore.fetch()
}
}
形が似ていますね。
KuriRepositoryImpl.swift
はKuriTemplate/Implement/Repository/Repository.swift
を基にして(テンプレートとして)作られています。
つまり、テンプレートを編集すれば次回以降のkuri generate XXX
コマンドから編集した内容が反映されます。
テンプレートをみて気づくと思うのですが、
__REPOSITORY__
, __DATASTORE__
と言う文字列があります。
これは見比べてもらうとわかると思うのですが、
kuri generate XXX
と実行するとそれぞれ
XXXRepository
, XXXDataStore
へと置きかわる変数の役割を果たしています。
以上のことを知っておけばテンプレート編集できます。
この機能を使用して自分のプロジェクトにあったテンプレを作成することが可能です。
締め
以上でKuriの紹介を終わります。
より詳細なことはgithub上のDocuments
フォルダやREADEMEに記載されているのでそちらをごらんください
https://github.com/bannzai/Kuri/
https://github.com/bannzai/Kuri/tree/master/Documents
generate
に関してもいくつかオプションが用意されているのでこちらを使うことで開発がよりスムーズになると思います。
まだ機能追加していくつもりですが、issue
公開して間もないのでPRやissueや要望・質問をお待ちしております^^
なぜKuri?
Kuriの名前の由来は
- Clean Architecture → クリーンアーキテクチャー → Kuriーンアーキテクチャー
- クリ(Kuri)スマスに公開したライブラリだから
と言うしょうもない親父ギャグです
\(^o^)/