iOSアプリをハッカソンで作るときに便利な初期プロジェクトを作ってみた


ハッカソンや小さなプロジェクトでiOSアプリを何度も0から作っている間に、同じようなコードを書いたり、コピペしたりしていることにつらみ(´･ω･`)を感じていました。

そこで、よく使っているオレオレプロジェクト構成やextensionなどをまとめた初期プロジェクトを作ってみました。(∩´∀｀)∩ﾜｰｲ

リポジトリはこちらです。
https://github.com/tattn/HackathonStarter

## 使い方

### 導入

まずはcloneしてきます。

```bash:zsh
$ git clone https://github.com/tattn/HackathonStarter hack
$ cd hack
```

次はCocoaPodsやCarthage,SwiftLintなどのチームで共通に必要なツールをインストールします。

```bash:zsh
$ ./tool/setup.sh
```

他にもチームで使いたいツールがある場合は、`tool/setup.sh`を編集して簡単にインストールできるように準備をすると、ジェントルマン:squirrel:になれます。

次はライブラリの導入です。
個人的にCocoaPodsよりもCarthageを使ったほうが、面倒なことにならないので積極的にCarthageを使っていきます。

```bash:zsh
$ vi Cartfile
$ carthage bootstrap --platform iOS
```

Alamofire, Realmなど、よく使うものはすでにプロジェクトに追加されています。新しく追加した場合や削除した場合はRun Scriptなどを修正してください。

ライブラリの関係などで、仕方なくCocoaPodsを使わなければならない時は、Gemfileを利用してCocoaPodsのバージョンをチームで揃えます。

```bash:zsh
$ bundle exec pod init
$ vi Podfile
$ bundle exec pod install
```

これで準備完了です。プロジェクトを開いて開発をスタートできます。

※補足
プロジェクト名はXcodeの機能を利用して一括で変更可能です。赤枠で囲っている部分の名前を変更し、Enterを押すと一括変更できます。
![HackathonStarter.png](https://qiita-image-store.s3.amazonaws.com/0/91631/93de5104-c929-2624-154e-eb54985adb87.png "HackathonStarter.png")

しかし、これだけではディレクトリ名は変わらないので、適宜変更してください。
[synx](https://github.com/venmo/synx)というツールを使用すると楽に変更できると思います。


### プロジェクトの構成

```
HackathonStarter
 ├── Application: アプリ全体の設定や機能用
 ├── Extension:   SwiftのExtension用
 ├── Manager:     Manager的な機能を持つクラス用
 ├── Model:       JSONマッピングなどをするモデル用
 ├── Protocol:    SwiftのProtocol用
 ├── UI:          UI関係のクラスやStoryboard用
 └── Utility:     ヘルパークラスなど用
```

デフォルトではこのようになっています。アーキテクチャに合わせて適宜変更してください。

## 機能の紹介

数が多すぎるので、よく使いそうなものを紹介します。

### Application

#### App

アプリの全体的な設定をまとめておくクラスです。

```swift:swift
App.screenWidth   // 横幅の取得
App.Color.main    // テーマカラーなどを定義します
App.Font.main(18) // テーマフォントなどを定義します
```

#### AppData

永続化しておきたいアプリの設定をまとめておくクラスです。

```swift:swift
// 保存
AppData.save(.Hoge, value: "hoge")

// 取得
let hoge: String = AppData.get(.Hoge)
```

※ AppDataKey(Enum)にキー名を追加して使用します。

### Manager

#### PushNotificationManager

Push通知を処理するクラスです。

```swift:swift
PushNotificationManager.allowToPushNotification()
```
↑Push通知を許可するか否かのダイアログが表示されます。

```swift:swift
static func sendDeviceToken(deviceToken: String) {}
```
↑初回やデバイストークンが変更された時に、呼び出されるメソッドです。引数のデバイストークンをサーバーに送る処理をよく書きます。

```swift:swift
static func handlePushNotification(userInfo: [NSObject : AnyObject], state: UIApplicationState) {}
```
↑プッシュ通知を受け取った時に呼び出されるメソッドです。`state`や`userInfo`を使用して、プッシュを受け取った時のアプリの動作を記述します。

#### PhotoAlbumManager

端末内の写真を扱うクラスです。

```swift:swift
PhotoAlbumManager.runIfAuthorized {
    // 写真を扱う処理
}
```
↑初回時に写真へのアクセス許可を求めるアラートを出し、許可されたorされている場合は中のクロージャを実行、許可されていない場合は、設定画面へ遷移させるアラートを表示します。

```swift:swift
PhotoAlbumManager.pickPhotoFrom(.PhotoLibrary) { image in
    if let image = image {
        // 写真が選択された場合
    }
}
```
↑端末内の写真一覧を表示し、ユーザーに選択をさせ、選択した場合はその写真を取得するメソッドです。引数を`.Camera`にすることでその場で写真を取ることもできます。

### Utility

#### Ionicons

[ionicons](http://ionicons.com/)という素晴らしいアイコンフォントを簡単に扱うためのヘルパークラスです。

```swift:swift
let icon: UIImage = Ionicons.IosSettings.image(30, color: .redColor())
```
↑赤色の設定アイコンを30ptのサイズで取得する例です。enumで定義されているので、簡単にアイコンを指定できます。

### UI

#### IBDesignable

Storyboardで角丸などの設定を行うためのクラス群です。

- IBDesignableView
- IBDesignableButton
- IBDesignableCollectionViewCell
...

など様々なクラスで使えるように用意しています。

これらのクラスを代わりに使うことで、`borderColor`, `borderWidth`, `cornerRadius`, `masksToBounds`などをStoryboardから設定できるようになります。


### Extension

以前投稿した「[使うと手放せなくなるSwift Extension集](http://qiita.com/tattn/items/647e094936287a6bd2d3)」に記載したextension+αが入っています。詳しくはそちらをご覧ください。

#### Realm拡張

```swift:swift
// HogeはRealmオブジェクト

// 全て取得
let hoges: [Hoge] = Hoge.all()

// 条件をつけて検索
let hoges = Hoge.findAll("name = %@", "taro") // nameがtaroのオブジェクトを全て取得

// 保存
let hoge = Hoge()
hoge.name = "taro"
hoge.save()
// hoges.save() // 配列も可

// 更新
hoge.write { _ in
    hoge.name = "hanako"
}

// 削除
Hoge.deleteAll("name = %@", "taro") // nameがtaroのオブジェクトを全て削除
hoge.delete()
hoges.delete()
```

## 最後に

全然説明しきれていないので、詳しくは[ソースコード](https://github.com/tattn/HackathonStarter)をご覧ください(´・ω・`)

かなり大きな初期プロジェクトになってしまったので、使用するときはチームメンバーに了承を取り、このQiitaをシェアするなどして混乱のないように注意してください。

皆さんの爆速開発に貢献できれば幸いです。:smile:

提案やプルリクもお待ちしております。:smiley: