Swiftでライブラリを公開する

[Wantedly Advent Calendar 2015](http://qiita.com/advent-calendar/2015/wantedly) 16日目です。

Swiftがオープンソース化されて、Swift3.0のロードマップが公開されたり、Swift package managerが出てきたり色々変化が起こりそうな（というか起こる）昨今ですが、今日（もう直ぐ朝）は、今現在使えるツールを利用してSwiftで書いたライブラリを公開する僕なりの方法を書いておこうと思います。[オープンソース活動が趣味](https://speakerdeck.com/morizotter/develop-with-swift)なので、書きます。

対象読者は、ライブラリをまだ公開したことがない人です。最近は、CarthageとCocoapods両方に対応することがトレンドなので両方に対応しやすいように作っていきます。

## この記事を読んでできること

- [Carthage](https://github.com/Carthage/Carthage) でライブラリを公開できる
- 同時に[Cocoapods](https://cocoapods.org/)でライブラリを公開できる
- ライブラリを公開するときのディレクトリ構成のイメージができる
- ライブラリを公開するときに必要なREADMEやLICENSEファイルについてわかる

## ライブラリについて

公開と書きましたが、Cocoapodsなどのディレクトリに登録して大げさにやる必要はありません。普段開発をしている際に、よく使うツールを「本体から独立させて」、「ちょっと整理して」「利用しやすくする」というだけです。なので、自分用ライブラリや、チーム用ライブラリなども全然ありです。Xcode7系になってビルド時間がだいぶ短くなりましたが、コードを分離して管理することでビルド時間をさらに削減できるという効果もあります。小さな単位で分離することで自然と綺麗にしようという気持ちが働き、コードもスッキリします。

## 公開して嬉しいこと

ただ、やはり公開すると嬉しいことも増えます。スターがついたりフォークが増えたりすると単純に嬉しいです。プルリクが来ると嬉しいです。使ってくれてるんだなと感じます。たまに、有名なエンジニアからIssueなどでコメントがつくと嬉しいです。[Githubのトレンド](https://github.com/trending?l=swift)に載ったりすると嬉しいです。Githubのページが派手になって嬉しいです。TwitterやSafariで定期的にライブラリ名を検索してしまいます。

## ディレクトリ構成

ディレクトリ構成はこんな感じになるのが良いと思います。ちなみに、[KeyboardObserver](https://github.com/morizotter/KeyboardObserver)というのは今回記事どおりできるか確認のために作ったマイクロライブラリです。

```
.
├── Demo
│   ├── Demo
│   │   ├── AppDelegate.swift
│   │   └── ...
│   └── Demo.xcodeproj
├── KeyboardObserver
│   ├── Info.plist
│   ├── KeyboardObserver.h
│   └── KeyboardObserver.swift
├── KeyboardObserver.podspec
├── KeyboardObserver.xcodeproj
├── LICENSE
└── README.md
```

特徴としては、ライブラリのフレームワークがあるprojectがトップレベルにあって、Demo用のprojectがディレクトリ下にあるというものです。Carthageで配布する場合projectがトップレベルにある必要があるのでこのような構成にしています。

こんな構成になるように作っていきます。

## 書いていく

### まずはプロジェクトを作ります

**Framework & Library** から **Cocoa Touch Framework** を選択します。

![framework.png](https://qiita-image-store.s3.amazonaws.com/0/24041/215175b7-85ab-7cc6-12c3-83411929ba18.png)

```
.
├── KeyboardObserver
│   ├── Info.plist
│   └── KeyboardObserver.h
└── KeyboardObserver.xcodeproj

```

まずはこういうディレクトリ構成になりました。

### 次にDemoプロジェクトを作ります

早速、Demoプロジェクトを作ります。いつも通り、Xcodeからプロジェクトを生成します。プロジェクトの場所は、KeyboardObserver.xcodeprojと同階層に配置します。Demoプロジェクトは開発するのにも便利だし、利用者にも親切なためです。プロジェクトを分ける理由は、ライブラリの動作確認をする際などに分離されていると何かと便利なことが多いためです。

![Demo.png](https://qiita-image-store.s3.amazonaws.com/0/24041/8b4921ed-d90e-f138-a6d7-02a7f7246392.png)

```
.
├── Demo
│   ├── Demo
│   │   ├── AppDelegate.swift
│   │   └── ...
│   └── Demo.xcodeproj
├── KeyboardObserver
│   ├── Info.plist
│   └── KeyboardObserver.h
└── KeyboardObserver.xcodeproj
```

こんな感じになったと思います。

### git init

だいたいこの辺りで`git init`をします。Githubに配布プロジェクトと同名のリポジトリを作るのですが、この段階で、READMEとMITのライセンスを選択します。そして、作成完了すると、下記のようにSSHのURLが生成されるのでこれを宛先にします。その後、Github上で作成したREADMEとLICENSEファイルをpullします。

<img width="1000" alt="morizotter_KeyboardObserver_swift 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/24041/fe3c70a4-0df0-1c92-3655-0c5a906ae419.png">

```bash
$ git remote add origin git@github.com:morizotter/KeyboardObserver.swift.git
$ git pull origin master
```

この段階で、下記のようなディレクトリ構成になったと思います。

```
.
├── Demo
│   ├── Demo
│   │   ├── AppDelegate.swift
│   │   └── ...
│   └── Demo.xcodeproj
├── KeyboardObserver
│   ├── Info.plist
│   ├── KeyboardObserver.h
│   └── KeyboardObserver.swift
├── KeyboardObserver.xcodeproj
├── LICENSE
└── README.md
```

開発の準備が整いました。

### 開発はDemoプロジェクトで行う

基本的に開発はすべてDemoプロジェクトで行います。

- ライブラリのファイルを追加するときは、ライブラリ用プロジェクトのディレクトリ（今回のケースでは `KeyboardObserver/` 下）に配置することを忘れないようにしましょう。
- Swiftはプロジェクトごとにmoduleという単位で分けられています。公開されるTypeやプロパティには `public` をつけて他のmoduleからも見えるようにしておきましょう。

### LICENSE

ライセンスはGithubのリポジトリを作るときに追加できるのでそれをそのまま使えば良いと思います。Githubで公開されているものはMITが多い印象なので、それにしています。

### README

スターを獲得するには重要な部分です。また、未来の自分や他人に理解してもらうためにも大事な部分です。簡易的なドキュメントと思えば気楽にかけます。最初は、どういう項目があれば良いかイメージできないと思うので有名なライブラリを参考にして書くと良いと思います。最低限あったほうが良いと思う項目は以下の通りです。

- Features
- How to use
- Runtime Requirements
- Installation and Setup
- License

Licenseはなくても良いような気もしますが、これがあると使う人の気が楽になるという効果があると思います。

## Carthageで配布する

ライブラリのプロジェクトを開き、schemeをsharedにします。

![KeyboardObserver_xcodeproj.png](https://qiita-image-store.s3.amazonaws.com/0/24041/bde9578d-70d5-994e-6a61-59aa6858e235.png)

```
$ carthage build --no-skip-current
```

コマンドを叩いて、出来上がったファイルを確認します。

詳しくは、[Carthageの配布の仕方（すっごい簡単！）](http://qiita.com/morizotter/items/56658ed7920059beaa8e)を見ていただくと良いと思います。

githubにpushしてバージョンをつけます。バージョンはreleaseの所からつけることができます。

<img width="1000" alt="morizotter_KeyboardObserver_swift.png" src="https://qiita-image-store.s3.amazonaws.com/0/24041/bc77cba8-fda2-a52b-d6eb-558e981990a5.png">

これでCarthage配布は完了です。先ほどのDemoプロジェクトのコピーを作ったり、Targetを分けたりして実際に動かしてみて想定どうりに動くか確認します。Carthageは個人用としても管理がとても簡単だし、Cocoapodsのようにprojectを書き換えたりされないので、とても便利に簡単に使えます。

## Cocoapodsで配布する 

次に、 [CocoaPods](https://cocoapods.org/) で配布します。現在のCocoapodsはコマンドがとても充実していてコマンドだけで簡単に公開することができます。ただ、Cocoapodsは公開するための、**podspec**というファイルが必要なので、まずそれを用意します。

*下記のコマンドを叩く際に初回はユーザー登録などが必要になるかもしれません。*

```bash
$ pod spec create https://github.com/morizotter/KeyboardObserver
Specification created at KeyboardObserver.podspec
```

これを書きます。KeyboardObserverのPodspecは[こちら](https://github.com/morizotter/KeyboardObserver/blob/master/KeyboardObserver.podspec)です。

書き終えたら、公開できるかチェックします。

```
$ pod lib lint KeyboardObserver.podspec

 -&gt; KeyboardObserver (0.2.1)

KeyboardObserver passed validation.
```

大丈夫！そしたら、公開します！

```
$ pod trunk push KeyboardObserver.podspec
Updating spec repo `master`
Validating podspec
 -> KeyboardObserver (0.2.1)

Updating spec repo `master`
  - Data URL: https://raw.githubusercontent.com/CocoaPods/Specs/4c52ccde884006d4828816d60536fae73da0ba77/Specs/KeyboardObserver/0.2.1/KeyboardObserver.podspec.json
  - Log messages:
    - December 16th, 04:02: Push for `KeyboardObserver 0.2.1' initiated.
    - December 16th, 04:02: Push for `KeyboardObserver 0.2.1' has been pushed (1.577866105 s).
```

公開できました〜。簡単！

## さらに

- bundlerでcocoapodsなどのバージョン固定
- バッジ
- test
- CIの整備
- fastlaneで自動化

などを用意するといいですね！

## 今回説明のために作成したライブラリ

- [morizotter/KeyboardObserver](https://github.com/morizotter/KeyboardObserver)

説明のために一通り書いた通りになるかライブラリを一つ作ってみました。iOSのキーボードの扱いはNSNotificationをキャッチして挙動を変える必要があって面倒くさいです。コードも散らかります。そのイベントを簡単に扱えるようにラップしたようなライブラリです。ぜひ、使ってみてください〜。

KeyboardObserverを説明した記事も書いてしまいました。 -> [iOSのキーボード周りの扱いを簡単にするKeyboardObserverを作りました - Qiita](http://qiita.com/morizotter/items/32136cc38d89520f11ec)