post Image
まだiOS Clean Architecture で消耗してるの? 爆速開発ツールを作ったのでご紹介

前置き

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

image

あとは展開したファイルを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.ymlKuriTemplateの作成が完了しました。

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 XXXXXXをprefixとしたファイルが一気にgenerateされ、
えさらにXcodeプロジェクトにimportされていることが確認できたと思います。

これだけのファイルをコマンド一発で用意できるなんて便利ですね!

generate 応用

ここではKuriに用意されたgenerateコマンドの柔軟性について少し触れたいと思います。
まず前提としてsetupコマンドで用意した二つのものの解説をします。
Kuri.ymlgenerateするための設定が記述されています。
具体的にはどのプロジェクトのどのターゲットをどのパスにファイルを作成するかを決めるための情報が記載されています。
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.swiftKuriTemplate/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の名前の由来は
1. Clean Architectureクリーンアーキテクチャー → Kuriーンアーキテクチャー
2. クリ(Kuri)スマスに公開したライブラリだから
と言うしょうもない親父ギャグです

\(^o^)/


『 Swift 』Article List