【初心者向け】iOSアプリの個人開発で便利だったライブラリ・ツール・サイト

はじめてのMacを買ったのが去年の4月、ジーズではじめてiOS触ったのが10月ごろ🍂
iOSとの出会いから早いもので1年以上経過しました（冬眠していた期間も相当ありますが…）😲

ここ一年、せっかく沢山のライブラリやツールを使ったので、iOS開発周りで便利だったものをいくつかピックアップしてご紹介いたします！（実際に全部使っている・いたものに限定してます）

ジーズのアドベントカレンダーといいつつiOSの人限定の記事で申し訳ないですが、これ見てなんかiOSも楽しそうだなって思ってもらえると嬉しいです😊

※記事内のスター数は2018/11/30時点
※いずれもmacOS Mojave 10.14.1（18B75）/Xcode Version 9.3 (9E145)/Swift 4.1で動いたものですが、ライブラリのバージョンはSwiftバージョンに合わせてるので、[使用例]はあくまで参考程度に

#ライブラリ
##アニメーション
###[marcosgriselli/ViewAnimator](https://github.com/marcosgriselli/ViewAnimator)　★4,663
【1行で】
Viewアニメーションのコード記述が簡単になるやつ

【もうちょっと解説】
使いすぎはうざったいですが、本当に必要な箇所で絞って使えば少しリッチになります。もっさりするアニメーションの記述もスッキリ見やすく、非常に使いやすいです。

【サンプル画像】
![cd8eb74f8a4276b22e2420be230d53d3.gif](https://qiita-image-store.s3.amazonaws.com/0/158756/36ab3406-afe1-331b-99af-4dae21395d03.gif)

【使用例】

```swift
//例えばセルのアニメーション
let fromAnimation = AnimationType.from(direction: .right, offset: 30.0)
let zoomAnimation = AnimationType.zoom(scale: 0.2)
let rotateAnimation = AnimationType.rotate(angle: CGFloat.pi/6)
UIView.animate(views: collectionView.visibleCells,
               animations: [zoomAnimation, rotateAnimation],
               duration: 0.5)
```

###[HeroTransitions/Hero](https://github.com/HeroTransitions/Hero) ★15,431
【1行で】
色々なトランジションがつけられるやつ

【もうちょっと解説】
サンプル画像にある「Match」の表現とかは今流行りですね。例えば「Match」とかだと、異なるVC間でidによるパーツの紐づけを行い、トランジションをかける感じになります。最近のAppStoreみたいなアニメーション自力でやるとなると中々骨が折れますが、これだとめちゃシンプルに書けますよね。

【サンプル画像】
![hero.gif](https://qiita-image-store.s3.amazonaws.com/0/158756/f95d0165-8683-0bc8-3c9d-38576abee520.gif)

【使用例】

```AViewController.swift
  //今回はAViewController⇔BViewControllerで「Match」をやってみます
  override func viewDidLoad() {
    super.viewDidLoad()
    self.aUpperView.hero.id = "upper"
    self.aLowerView.hero.id = "lower"
  }

  @objc override func onTap() {
    let bVC = BViewController()
    bVC.hero.isEnabled = true
    present(bVC, animated: true, completion: nil)
  }
```
```BViewController.swift
  override func viewDidLoad() {
    super.viewDidLoad()
    self.bUpperView.hero.id = "upper" //aUpperViewはこれだよ
    self.bLowerView.hero.id = "lower" //aLowerViewはこれだよ
  }
```

###[MengTo/Spring](https://github.com/MengTo/Spring)  ★12,760
【１行で】
UIKitのパーツに色々な挙動を簡単に足せるやつ

【もうちょっと解説】
StoryBoardからでもコードからでもボタンやViewに簡単にアニメーションをつけられます。よくあるエラーのぶるぶるってやつも一瞬です。色々なアニメーションの種類もあるし、速さや回数、逆再生などちょっとした調整もすぐできます。

【サンプル画像】
![d5f67245567ddff19790017e62ad04ab.gif](https://qiita-image-store.s3.amazonaws.com/0/158756/d4d04752-6f83-a4cb-79e8-ab37352f3d1e.gif)


【使用例】

```swift
@IBOutlet weak var modalView: SpringView!
//途中略
self.modalView.animation = "shake"
self.modalView.animate()
```

###[airbnb/lottie-ios](https://github.com/airbnb/lottie-ios) ★15,610
【１行で】
AfterEffectsで作ったアニメーション(JSON)を表示できるやつ

【もうちょっと解説】
AfterEffectsにBodyMovinというプラグインを追加して、JSONを出力してそれをXcode側に取り込みます。出来る表現に限りはありますが、動画などと違ってかなり軽量です。JSONによる単なるアニメーション表示だけでなく、AfterEffectsのレイヤーを指定してUIImageをはめこんだりもできます。
一部の効果は描画できないものもあるので公式サポートをよく読みましょう（Web版とiOS版とで機能に差分があるので注意）。
https://airbnb.io/lottie/supported-features.html

【サンプル画像】
<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/158756/0e3b249c-d8fc-88ca-9b05-45e8d771a004.gif">

【使用例】

```swift
let animationView = LOTAnimationView(name: "json_name")

animationView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
animationView.center = self.view.center
animationView.loopAnimation = false
animationView.contentMode = .scaleAspectFit
self.view.addSubview(animationView)

animationView.play{ (finished) in
  self.dismiss(animated: true, completion: nil)
}
```
##色
###[viccalexander/Chameleon](https://github.com/viccalexander/Chameleon) ★11,671

【１行で】
色の扱いを色々簡単にするやつ

【もうちょっと解説】
フラットカラーの取得、背景色から読みやすい文字色を取得、明暗類似色の取得、画像からの平均色を取得、グラデーション設定(中心/縦/横)、HEXカラーのサポートなど、色にまつわる便利な機能が沢山あります。PhotoShopやSketchのパレットをインポートすることも可能です。

【使用例】

```swift
//フラットカラー呼び出し
view.backgroundColor = FlatGreen()
//読みやすい文字色を取得
let backgroundColor = self.hoge.backgroundColor
let color = ContrastColor(backgroundColor, true)
//グラデーション
let gradientColors = [.red,.green,.blue]
let gradientColor = GradientColor(.topToBottom, frame, gradientColors)
```

##ローディング

###[ninjaprox/NVActivityIndicatorView](https://github.com/ninjaprox/NVActivityIndicatorView) ★7,707
【１行で】
いい感じに読み込み中のぐるぐるを出すやつ。

【もうちょっと解説】
最初から以下の画像のバリエーションのぐるぐる(インディケーター)が使えます。ぐるぐるViewを組み込んだ、自作Viewを作ったりもできますし、「NVActivityIndicatorViewable」でUIブロックしてユーザー操作を受け付けないような状態にしてぐるぐるを出すこともできます。フェードアニメーションつけてスムースな表示も可能。

【サンプル画像】
<img width="200" src="https://qiita-image-store.s3.amazonaws.com/0/158756/af3407ac-88ea-564d-f6f0-4d6553c04359.gif">

【使用例】

```swift
@IBOutlet weak var indicatorView: NVActivityIndicatorView!
//途中略
indicatorView.startAnimating() //開始
indicatorView.stopAnimating() //終了
```

###[Juanpe/SkeletonView](https://github.com/Juanpe/SkeletonView) ★6,300
【１行で】
FacebookとかYouTubeみたいなローディング画面

【もうちょっと解説】
ただのローディングだと、「今どんな状態なんだろ...?」「これからどうなるの...?」感があるので、「今ここに表示する情報を読み込んでいるのですよ！」と明示することで、ユーザーは次の操作をイメージしやすくなり、UXの改善につながります。
TableViewで使う場合は、ダミーのセルをいくつか表示のうえ、カスタムセルのawakeFromNibでSkeletonを有効にしておいて、読み込みが終わったらリロード時にSkeletonを無効にして更新すると良いと思います。

【サンプル画像】
![53f1eb176a1e78ddf1356f76708d77ec.gif](https://qiita-image-store.s3.amazonaws.com/0/158756/855c98c5-67ed-5e38-69a8-82b52534d982.gif)

【使用例】

```swift
@IBOutlet weak var label: UILabel!
//途中略
label.isSkeletonable = true //Skeletonにする
label.isSkeletonable = false //Skeletonやめる
```

##Table/Collection

###[dzenbot/DZNEmptyDataSet](https://github.com/dzenbot/DZNEmptyDataSet) ★10,925
【１行で】
いわゆるエンプティステート

【もうちょっと解説】
UITableView/UICollectionViewが空だと寂しい。そんなときに、タイトル、説明文、ボタン、画像などを表示できます。「○○が登録されていません 新しく○○を作成してみましょう」というような説明文とボタンを設置しておくことで、「なぜ表示されないのか」「次に何をするのか」が分かりやすくなります。

【サンプル画像】
![Screenshots_row1.png](https://qiita-image-store.s3.amazonaws.com/0/158756/b33a254f-85d3-4789-866d-d0aff78841dc.png)

【使用例】

```swift
//途中略
    self.tableView.emptyDataSetSource = self;
    self.tableView.emptyDataSetDelegate = self;
}
//途中略
extension ViewController: DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
    func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
        return UIImage(named: "icon-empty")
    }
    func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
            let text = "○○はありません"
            let font = UIFont.boldSystemFont(ofSize: 18)
            return NSAttributedString(string: text, attributes: [NSAttributedStringKey.font: font,NSAttributedStringKey.foregroundColor: .black)])
        }
    }
    func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
        let text = "○○を新しく作成してみましょう"
        let font = UIFont.systemFont(ofSize: 14)
        return NSAttributedString(string: text, attributes: [NSAttributedStringKey.font: font,NSAttributedStringKey.foregroundColor: .black])
    }
    func buttonImageForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> UIImage! {
        return UIImage(named: "btn-entry")
    }
    func emptyDataSetDidTapButton(scrollView: UIScrollView!) {
        self.doSomething()
    }
}
```

###[SwipeCellKit/SwipeCellKit](https://github.com/SwipeCellKit/SwipeCellKit) ★3,894 
【１行で】
スワイプアクションを便利にするやつ。

【もうちょっと解説】
スペース枯渇問題が起きがちなTableViewですが、ユーザーアクションをスワイプにもっていくことで意外とすっきりする場合もあります。スワイプで表示される箇所に好きな画像を入れたり自由度の高い表現をすることが可能です。
そもそも、iOS11からTableViewにスワイプアクションメソッドが追加され、左右への表示や画像の表示もできるのですが、それよりかは幅広い表現を簡単に実現できますし、ハンドリングも簡単です。

【サンプル画像】
![Expansion-Delegate.gif](https://qiita-image-store.s3.amazonaws.com/0/158756/4925b5c1-bfda-6d40-ab72-334b653aec4b.gif)

【使用例】

```swift
 var defaultOptions: SwipeTableOptions  = SwipeTableOptions()
 var isSwipeRightEnabled: Bool = true
 var buttonDisplayMode: ButtonDisplayMode = .titleAndImage
 var buttonStyle: ButtonStyle = .circular
//途中略
 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       let cell = tableView.dequeueReusableCell(withIdentifier: "MailCell") as! OwnCell
       //セルにSwipeCellのdelegateつける
       cell.delegate = self
       return cell
 }
//途中略
extension ViewController: SwipeTableViewCellDelegate {
   func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
       //Swipeアクションを指定(例：右にデリート)
       if orientation == .right {
            let deleteAction = self.deleteAction()//return SwipeAction
            configure(action: deleteAction, with: .trash, alphaFlg: false)
            return [deleteAction]
        }
    }
    
    func configure(action: SwipeAction, with descriptor: ActionDescriptor, alphaFlg: Bool) {
        action.title = descriptor.title(forDisplayMode: buttonDisplayMode)
        action.image = descriptor.image(forStyle: buttonStyle, displayMode: buttonDisplayMode)
        action.textColor = descriptor.color
        action.backgroundColor = .white)
        action.font = .systemFont(ofSize: 13)
        action.transitionDelegate = ScaleTransition.default
    }
    
    func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeTableOptions {
        var options = SwipeTableOptions()
        options.expansionStyle = orientation == .left ? .none : .destructive(automaticallyDelete: false)
        options.transitionStyle = defaultOptions.transitionStyle     
        switch buttonStyle {
        case .circular:
            options.buttonSpacing = 4
        }
        return options
    }
    func createArchiveDeleteAction() -> SwipeAction {
        return SwipeAction(style: .destructive, title: "削除") { action, indexPath in
        //なんかする
        }
    }
```

###[xmartlabs/Eureka](https://github.com/xmartlabs/Eureka) ★9,294
【１行で】
TableViewのフォーム作成が簡単なコード記述で可能に

【もうちょっと解説】
テキストフィールド付き、遷移付き、UI switch付き、TableViewのフォーム作成で大体のユースケースを網羅しています。もちろんカスタマイズして独自の複雑なセルをつくることもできます。UIにこだわらないところは、これでサクッと作っちゃいましょう。

【サンプル画像】
![eureka.gif](https://qiita-image-store.s3.amazonaws.com/0/158756/6ce343a4-3359-aebd-f85f-5bbee7d32ee2.gif)

【使用例】

```swift
func setUpForm(){
  form +++ Section("ProfileSection")
    <<< TextRow(){ row in
        row.title = "氏名"
        row.placeholder = "氏名を入力"
    }
    <<< PhoneRow(){
        $0.title = "電話番号"
        $0.placeholder = "電話番号を入力"
    }
  +++ Section("OrderSection")
    <<< DateRow(){
        $0.title = "受取日"
        $0.value = Date()
    }
}
```

##TabBar
###[Ramotion/animated-tab-bar](https://github.com/Ramotion/animated-tab-bar) ★9,505
【１行で】
TabBarにアニメーションをつける

【もうちょっと解説】
見た目やアニメーションはもちろんですが、RAMAnimatedTabBarControllerを承継したClassを作ったりして、挙動に関しても細かいカスタマイズもできます。RamotionさんのライブラリはかっこいいUI表現が多いので、他のライブラリも見てみると楽しいです。

【サンプル画像】
<img width="300" src="https://qiita-image-store.s3.amazonaws.com/0/158756/35fd60c3-4461-7c0b-302a-4874d81c975a.gif">

【使用例】

```swift
//バッジ表示
@IBAction func showBadgeHandler(_: AnyObject) { 
  self.index += 1
  tabBarItem.badgeValue = "\(index)" |
}

//独自に挙動のロジックを実装
@objc open override func tapHandler(_ gesture: UIGestureRecognizer) {
  //例えば真ん中押したときだけModal出すとか
}
```

##ページャー
###[xmartlabs/XLPagerTabStrip](https://github.com/xmartlabs/XLPagerTabStrip)　★5,573
【1行で】
タブメニューでビューを切り替えるやつ

【もうちょっと解説】
マネーフォワードとかスマニューとかタブ型のメニューは未だ多くのアプリで現役で使われていると思います。XLPagerTabStripは見た目のカスタマイズも簡単で、さくっとタブ型のメニューを組込みたい場合にとても便利。

【サンプル画像】
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/158756/84b27c27-3c82-59c5-97a1-3b657958c01e.gif">

【使用例】

```ParentViewController.swift
class ParentViewController: ButtonBarPagerTabStripViewController {
//省略
override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
  let leftVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Left")
  let rightVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Right")
  let childViewControllers:[UIViewController] = [leftVC, rightVC ]
        return childViewControllers
}
```
```ChildLeftViewController.swift
class ChildLeftViewController: UIViewController, IndicatorInfoProvider {
var itemTitle: IndicatorInfo = "ひだり"
//省略
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
  return itemTitle
}
```

##画像
###[SDWebImage](https://github.com/SDWebImage/SDWebImage)　★20,778
【1行で】
外部の画像読み込みに使うやつ

【もうちょっと解説】
画像のキャッシュや非同期での画像のダウンロードをサポートしてくれます。
二強（！？）のうちの１つ、[Kingfisher](https://github.com/onevcat/Kingfisher)とも比較してみるといいと思います。
Firebase Storage使ってる場合は、FirebaseUI/Storageで。

【使用例】

```swift
//外部から通常
normalImageView.sd_setImage(with: URL(string: "https://hogehoge/img.jpg"), placeholderImage: nil)
//Firebase Storageから取得
fbImageView.sd_setImage(with: firebaseStorageRef, placeholderImage: nil)
```

##フォント
###[thii/FontAwesome.swift](https://github.com/thii/FontAwesome.swift) ★1,090
【１行で】
Icon Fontをつかいやすくするやつ

【もうちょっと解説】
FontAwesomeKitとか色々あるんですが、こちらはまあまあ直近もメンテされてる印象だったので使ってみました。

【使用例】

```swift
//ボタンにアイコン表示
self.nextBtn.titleLabel?.font = UIFont.fontAwesome(ofSize: 20, style: .brands)
self.nextBtn.setTitle(String.fontAwesomeIcon(name: .arrowAltCircleRight), for: .normal)

//ImageViewにアイコン表示
self.imageView.image = UIImage.fontAwesomeIcon(
  name: .handHoldingHeart
  style: brands,
  textColor: .black,
  size: CFSize(width: 200, height: 200)
)
```

##チャット
###[MessageKit/MessageKit](https://github.com/MessageKit/MessageKit) ★2,528
【１行で】
チャットを簡単に作るやつ

【もうちょっと解説】
フルスクラッチでチャットを作って死んだ私ですが、個人開発のアプリを最近これに載せ替えました。今年ver1.0を超えて、現在ver2になっています。DEPRECATEDとなったJSQMessagesViewControllerの代替となるであろうライブラリ。ロードマップも公開されてきっちりメンテされている印象。カスタマイズも簡単。

【サンプル画像】
<img width="250" src="https://qiita-image-store.s3.amazonaws.com/0/158756/2bb1c986-07e6-0dbe-a843-88b537ce67fb.png">

【使用例】
一部だけ切り取ってもわけわからないと思うのでパス
余裕があったら別記事でカスタマイズとかについて書きます

##バッジ
###[cwRichardKim/RKNotificationHub](https://github.com/cwRichardKim/RKNotificationHub) ★2,980
【１行で】
よくあるバッジをいい感じに表示するやつ

【もうちょっと解説】
viewやアイコンの好きなところにバッチ表示することが可能。

【サンプル画像】
<img width="400" src="https://qiita-image-store.s3.amazonaws.com/0/158756/d801ceaa-e3b5-3e1e-6a11-54b0a9010fa8.gif">

【使用例】

```swift
let hub = RKNotificationHub()
let hogeBtn = UIButton()
var count = 0

func setUpHub(){
    self.hub.setView(self.hogeBtn, andCount: Int32(count))
    self.hub.setCircleColor(.red, alpha: 1), label: UIColor.white)
    self.hub.moveCircleBy(x: -5, y: 20)
    self.hub.scaleCircleSize(by: 0.5)
}
```

##デバイス判定
###[dennisweissmann/DeviceKit](https://github.com/dennisweissmann/DeviceKit) ★2,400
【１行で】
デバイス判定をさくっとするやつ

【もうちょっと解説】
端末ごとに処理を分けたい時に便利。7以降だったらHeptic feedback返すけど、そうでなければ違うアクション返すとか、ちょっとしたレイアウトの微調整とか。シュミレーターかつ、この端末バージョンだけといった指定もできます。また、簡単な記述で、バッテリーの残量や低電力モードの状態、スクリーンの明るさなどの切り分けもできます。

【使用例】

```swift
let allowedDevices: [Device] = [.iPhone7Plus, .iPhone6sPlus, .simulator(.iPhone7Plus), .simulator(.iPhone6Plus)]
let device = Device()
 
if device.isOneOf(groupOfAllowedDevices) {
  self.doSomething()//allowedDevicesに対して何かする
}
```

##UserDefaults
###[SwiftyUserDefaults](https://github.com/radex/SwiftyUserDefaults) ★3,553
【１行で】
UserDefaultsを安全に扱いやすくする

【もうちょっと解説】
下記の使用例に記載したように、extentionで好きなだけプロパティを追加して、好きなだけ使ってください。別ファイルで、
生でUserDefaultsを扱うとコードがみずらいですが、まとめて定義しておくことで、非常に安全かつ簡単に扱うことができます。

【使用例】

```swift
extension DefaultsKeys {
    static let username = DefaultsKey<String>("username")
    static let launchCount = DefaultsKey<Int>("launchCount")
}
```
```swift
//Defaults[.hoge]がいやな人はこんな感じでまとめておくとか
class Defaults {
    static let shared: Defaults = {
        return Defaults()
    }()

    var username: String {
        get { return Defaults[.username] }
        set(value) { Defaults[.username] = value }
    }
    
    var launchCount: Int {
        get { return Defaults[.launchCount] }
        set(value) { Defaults[.launchCount] = value }
    }
}
```
```swift
//使ってみる
let username = Defaults.shared.username
Defaults.shared.launchCount = 8
```

##JSON
###[SwiftyJSON/SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON) ★17,760
【１行で】
JSONの扱いを簡単にする

【もうちょっと解説】
もはやSwift4からCodableプロパティが使えるので不要説もありますが、一応定番ということで。ということで使用例はQiitaにたくさんある記事を参考にくださいまし(少し疲れた)。

##チュートリアル
###[yukiasai/Gecco](https://github.com/yukiasai/Gecco) ★1,727
【１行で】
チュートリアルが簡単につくれる

【もうちょっと解説】
特定の箇所にスポットライトを作ったオーバーレイのVCを表示して、チュートリアルなどで使えるライブラリ。スポットライト内のタップ判定や、スポットライトのシームレスな変形・移動などもできるので素敵です。

【サンプル画像】
<img width="250" src="https://qiita-image-store.s3.amazonaws.com/0/158756/d23b9443-a1c2-5db6-53c2-e30558310688.gif">

【使用例】

```swift
class TutorialViewController: SpotlightViewController {
    //途中省略
    func next(_ labelAnimated: Bool) {
        updateAnnotationView(labelAnimated)
        switch stepIndex {
        case 0:
            spotlightView.appear(Spotlight.RoundedRect(center: CGPoint(x: screenWidth / 2, y: statusBarHeight + 112), size: CGSize(width: screenWidth - 10, height: 100), cornerRadius: 6), duration: 1)
        case 1:
            spotlightView.move(Spotlight.RoundedRect(center: CGPoint(x: screenWidth / 2, y: statusBarHeight + 112), size: CGSize(width: screenWidth - 10, height: 100), cornerRadius: 6), duration: 1)
        case 2:
            spotlightView.move(Spotlight.Oval(center: CGPoint(x: screenWidth - 84, y: statusBarHeight + 20), diameter: 50))
        case 3:
            spotlightView.move(Spotlight.Oval(center: CGPoint(x: screenWidth - 43, y: statusBarHeight + 20), diameter: 50))
        default:
            dismiss(animated: true, completion: nil)
        }
        stepIndex += 1
    }
    
    func updateAnnotationView(_ animated: Bool) {
        annotationViews.enumerated().forEach { index, view in
            UIView.animate(withDuration: animated ? 0.25 : 0) {
                view.alpha = index == self.stepIndex ? 1 : 0
            }
        }
    }
}

extension TutorialViewController: SpotlightViewControllerDelegate {
    func spotlightViewControllerWillPresent(_ viewController: SpotlightViewController, animated: Bool) {
        next(false)
    }
    
    func spotlightViewControllerTapped(_ viewController: SpotlightViewController, isInsideSpotlight: Bool) {
        if isInsideSpotlight {
            next(true)
        }
    }
    
    func spotlightViewControllerWillDismiss(_ viewController: SpotlightViewController, animated: Bool) {
        spotlightView.disappear()
    }   
}
```

##ポップアップ
###[SwiftKickMobile/SwiftMessages](https://github.com/SwiftKickMobile/SwiftMessages) ★4,055
【１行で】
アプリ内メッセージやポップアップなどを簡単に

【もうちょっと解説】
スター数の割にはあまり紹介記事を見かけたことがないのですが、これは今もお気に入りのライブラリです。アプリ内メッセージやちょっとしたポップアップで使うVCのpresentを簡単に実現できます。サンプル画像の下の方のSwiftMessagesSegueという機能もStoryBoardいじらずに実現できて非常に使いやすいです。

【サンプル画像】
![demo.png](https://qiita-image-store.s3.amazonaws.com/0/158756/b58a35fb-d2b7-fd83-0735-350a751a85a1.png)
![SwiftMessagesSegue.gif](https://qiita-image-store.s3.amazonaws.com/0/158756/98059b33-655c-d404-15b5-f12d79e51420.gif)

【使用例】

```swift
//中央にメッセージを出す
func centerMessage() {
    let messageView: MessageView = MessageView.viewFromNib(layout: .centeredView)
    messageView.configureBackgroundView(width: 250)
    messageView.configureContent(title: "おはようございます", body: "今日の天気は\(weatherString)です", iconImage: nil, iconText: weatherEmoji, buttonImage: nil, buttonTitle: "閉じる") { _ in
        SwiftMessages.hide()
    }
    messageView.backgroundView.backgroundColor = UIColor.init(white: 0.97, alpha: 1)
    messageView.backgroundView.layer.cornerRadius = 10
    var config = SwiftMessages.defaultConfig
    config.presentationStyle = .center
    config.duration = .forever
    config.dimMode = .blur(style: .dark, alpha: 1, interactive: true)
    config.presentationContext  = .window(windowLevel: UIWindow.Level.statusBar)
    SwiftMessages.show(config: config, view: messageView)
}

//SwiftMessagesSwgueをつかってみる
@IBAction func nextVCBtnTapped(_ sender: Any) {
    let destinationVC = self.storyboard.instantiateViewController(withIdentifier: "next")
    let segue = SwiftMessagesSegue(identifier: "ToFilterStatus", source: self, destination: destinationVC)
    segue.presentationStyle = .center
    segue.configure(layout: .centered)
    segue.messageView.backgroundHeight = CGFloat(300)
    self.prepare(for: segue, sender: nil)
    segue.perform()
}
```

##日付
###[malcommac/SwiftDate](https://github.com/malcommac/SwiftDate) ★4,368
【１行で】
Swiftでの日付の扱いを簡単にするやつ

【もうちょっと解説】
JSでいう「date-fns」的な感じで、煩わしいフォーマット変換や日付計算などが非常に簡単にできます。いつもなら、formatterやらcalendarやら用意したりごにょごにょしがちですが、SwiftDateを入れただけで、書いたコードが非常にすっきりします。

【使用例】

```swift
//日付の計算も簡単
let lastChristmas = Date() - 1.year
let aMonthAfter = lastChristmas + 1.month 

//コンポーネントの取得も簡単
let year = lastChristmas.year

//文字列⇔日付変換もラクラク
let xmasDate = "2018/12/25".date(format: .custom("yyyy/MM/dd"))
let xmasString = xmasDate.string(custom: "yyyy年M月d日(EEEEE)")

//月初とったり
let beginningOfMonth = Date().dateAtStartOf(.month)
//間隔をとったり
let hours = Date().getInterval(toDate: lastChristmas, component: .hour)
//リージョンかえたり
let inGMT = dateInNY.convertTo(region: Region.UTC)
//他にも比較のメソッドとかよくあるやつは代替あります
```

##タイポ
###[mac-cain13/R.swift](https://github.com/mac-cain13/R.swift)　★5,550
【1行で】
タイポをなくすやつ

【もうちょっと解説】
R.swiftを導入することで文字列指定がなくなり、タイポミスが原因のバグ発生を防ぎます。また、同時にコード補完の恩恵を受けれるという利点もあります。「R」自体はR.generated.swiftにstructでまとめて定義されていて、そこから呼び出すようになっています。重くなったり、ビルドが遅かったりしたので、今はenumとか定数まとめファイルを作ってやってます。

【使用例】

```new.swift
let icon = R.image.profileIcon()
let color = R.color.primaryBackground()
let viewController = SurveyViewController(nib: R.nib.surveyView)
let lightFontTitle = R.font.acmeLight(size: 22)
let welcomeMessage = R.string.localizable.welcomeMessage()
```
```old.swift
//元はこうだった
let icon = UIImage(named: "profile-icon")
let color = UIColor(named: "primary background")
let viewController = SurveyViewController(nibName: "SurveyView", bundle: nil)
let lightFontTitle = UIFont(name: "Acme-Light", size: 22)
let welcomeMessage = NSLocalizedString("welcome.message", comment: "")
```

##AutoLayout
###[SnapKit/SnapKit](https://github.com/SnapKit/SnapKit)　★13,945
【1行で】
AutoLayoutをコードで簡単に書くやつ

【もうちょっと解説】
NSLayoutConstraintを使ってオートレイアウトの制約をつけると、かなり長いコードになってしまいます。そんなときはこれを使うとスッキリきれいに見やすいコードを書くことができます。類似のもので[PureLayout](https://github.com/PureLayout/PureLayout)があります。

【使用例】

```swift
lazy var testView = UIView()

override func viewDidLoad() {
     super.viewDidLoad()

     self.view.addSubview(testView)
     testView.snp.makeConstraints { (make) -> Void in
          make.width.height.equalTo(100)
          make.center.equalTo(self.view)
     }
}
```

##タップ表示
###[morizotter/TouchVisualizer](https://github.com/morizotter/TouchVisualizer)　★657
【1行で】
タップを表示するやつ

【もうちょっと解説】
デモをするときにどこをタッチしているか分からないと、見ている側も理解しづらい場合もありますよね。ジーズ生はプレゼンやデモが多いと思うので、デモ版ではこれを入れておくと良いかと思います。

【使用例】

```AppDelegate.swift
func applicationDidFinishLaunching(_ application: UIApplication) {
	var config = Configuration()
	config.color = UIColor.red
	config.showsTimer = false
	config.showsTouchRadius = true
	config.showsLog = false
	config.image = UIImage(named: "circle")
	Visualizer.start(config)
	//カスタムしない場合はVisualizer.start()だけでOK
}
```

---
#サービス・SDK・ツールなどで便利だったもの
##デバック
###[SwiftyBeaver/SwiftyBeaver](https://github.com/SwiftyBeaver/SwiftyBeaver) ★3,940
【１行で】
デバッグログがわかりやすくなる

【もうちょっと解説】
ビルドごとにログを出し分けたり、ログの種別ごとに色を変えたりすることができるので、デバックログの不要な検索の手間が減り、管理しやすくなります。
あまり必要性が分かりませんが、Macにアプリをインストールすれば、専用画面で仕込んだデバックログを眺めることもできます。

【サンプル画像】
<img width="608" alt="ac065a98-7ce6-11e6-8e1b-2a062d54a1d5.png" src="https://qiita-image-store.s3.amazonaws.com/0/158756/84a9040a-ce5d-f8eb-a87c-7c951870ff47.png">

【使用例】

```swift
let log = SwiftyBeaver.self
let console = ConsoleDestination()//xcodeでログ出力
log.addDestination(console)
 
log.verbose("not so important")
log.debug("something to debug")
log.info("a nice information")
log.warning("oh no, that won't be good")
log.error("ouch an error did occur!")
```

##ライセンス表記
###[mono0926/LicensePlist](https://github.com/mono0926/LicensePlist) ★1,310
【1行で】
設定画面にライブラリ表記をまとめて表示できるやつ

【もうちょっと解説】
自動的に依存ライブラリをiPhoneの設定画面に掲載してくれるツール。CocoaPods/Carthageどちらにも対応してくれています。podでLicense Plistを入れて、Build PhasesにRun Scriptを追記して自動更新に対応させるだけでOK。

【サンプル画像】
<img width="250" alt="IMG_0046.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/158756/f302d289-3142-81c4-aee6-183b2b4f33ec.jpeg">

【使用例】
こちらについては主に設定の話になるので本家のサイトをご確認くださいませ
https://medium.com/swift-column/license-plist-c0363a008c67

##画像作成
###[MakeAppIcon](https://makeappicon.com/)
【1行で】
アプリアイコンを自動で作成してくれるやつ

【もうちょっと解説】
1536 x 1536 pixでマスター画像を作成して、トースターが書いてあるところからぶち込むだけで全サイズ作成してくれます。

【サンプル画像】
<img width="400" alt="スクリーンショット 2018-11-27 11.33.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/158756/61f02b46-354d-0202-497f-02959c1a7c39.png">
###[Icon8](https://icons8.jp/) 
【1行で】
色んなアイコン素材

【もうちょっと解説】
最小サイズのPDFファイルでアイコンをさくっとダウンロードできるのでとても便利です。PDFでSingleScaleにしちゃった方が、画像設定も楽ですよね。有料版にすると、デスクトップアプリから色々探せるようになるので、アイコンが何かと必要になる開発初期やプロトタイプ作成時にはとても助かります。

【サンプル画像】
<img width="400" alt="Icon8" src="https://qiita-image-store.s3.amazonaws.com/0/158756/58353169-c20c-1686-76b3-05ccc89d7b30.png">

##まとめサイト
###[raywenderlich/swift-algorithm-club](https://github.com/raywenderlich/swift-algorithm-club) ★18,927
【１行で】
Swiftのアルゴリズムとデータ構造のまとめリポジトリ

【もうちょっと解説】
スタック/キュー/挿入ソート/バイナリ検索/線形探索/マージソート/ボイヤームーアの文字列検索など、主要なアルゴリズムやデータ構造をソースコード付きでまとめてくれている（すぐに試せるPlayGroundもついている！）ので、ジーズの人みたく独学スタイルでSwiftをやる人は基本が終わったらこういったものを合間に試してみるのも良いと思います。

###[CosmicMind/Material](https://github.com/CosmicMind/Material) ★10,542
【１行で】
マテリアルデザインのサンプル

【もうちょっと解説】
こういうUIライブラリ使わずにどういう風に作ればいいんだろ？？というときにヒントになるので、ちょいちょい使えます。

【サンプル画像】
<img width="500" alt="CosmicMind/Material" src="https://qiita-image-store.s3.amazonaws.com/0/158756/11b6b708-e848-8a8e-52a5-8d49a1eddddf.gif">

###[vsouza/awesome-ios](https://github.com/vsouza/awesome-ios) ★28,729
【１行で】
iOSで使えるライブラリやツールをまとめてるやつ

【もうちょっと解説】
カテゴリごとにライブラリやXcodeプラグイン、チュートリアルなどがまとめてあります。これも検索用にブクマしといてもよいと思います。

###[Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/)
【１行で】
iOSのUIではどんなことに気をつけるべきかのまとめ

【もうちょっと解説】
Appleの公式ドキュメント。２つのボタンが横並びの場合、こういうものを左に置きましょうとか、タップする箇所は44px確保しましょうとか、基本原則について分かりやすくまとめてくれています。Appleのアプリはなぜ使いやすいのかが分かりますよね。本編は英語ですが、例えばこんな感じのことが載っています。
https://developer.apple.com/jp/design/tips/
更新された際は何が変わったのかを見てみると、よりiOS開発の面白みも増してくるのかなと思います。

##審査期間
###[Average App Store Review Times](http://appreviewtimes.com/)
【１行で】
最近のAppleの審査期間の目安を教えてくれる

【もうちょっと解説】
最近は初回申請以外概ね1営くらいで通ると思うのであまり必要ないかと思いますが、審査期間の目安になるとは思います。たまに大量スパムで審査期間がめちゃくちゃ長く表示されるときがありますが。

【サンプル画像】
<img width="500" alt="Average App Store Review Times" src="https://qiita-image-store.s3.amazonaws.com/0/158756/babe7088-ac8f-22e0-566a-f350b78b0f28.png">

##分析
###[Google Analytics](https://developers.google.com/analytics/) 
【1行で】
アプリの分析に使うやつ

【もうちょっと解説】
実際アプリを作ったあとはほぼ必須のツールなのではないでしょうか。今、僕のアプリのバックエンドはFirebaseなので、現状はタグマネでFirebase Analyticsのイベントを拾ったりして、すぐにGoogleAnalyticsで主要KPIのレポートを作成できるようにしています。

##カスタマーサポート
###[Instabug](https://instabug.com/)
【１行で】
バグ報告/問い合わせなどの機能を実装

【もうちょっと解説】
キャプチャを添えたバグ報告や問い合わせ機能をすぐに用意できる。有料版では無料版の機能に加えアンケート(良い結果の人だけレビュー依頼するとか）や、機能リクエスト機能、app内サポートチャット、遷移やView Hierarchieの送信、各種インテグレーションなどとても便利な機能がたくさん使えます。詳しくはリンクから。実装もめちゃくちゃ簡単でヤバい。

【サンプル画像】
<img width="250" alt="IMG_0013.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/158756/64685b12-caad-5298-dab4-bd066342ed8e.jpeg">

【使用例】

```AppDelegate.swift
    //didFinishLaunchingWithOptionsで色々設定
    private func setupInstaBug() {
        Instabug.start(withToken: "token_here", invocationEvents: [.shake])
        Instabug.tintColor = .blue
        Instabug.setLocale(.japanese)
        Instabug.welcomeMessageMode = IBGWelcomeMessageMode.disabled
        BugReporting.promptOptions = [.feedback, .bug]
        BugReporting.shakingThresholdForiPhone = 2.0
        BugReporting.didDismissHandler = { (dismissType, reportType) in
            self.doSomothing()//閉じたときになんかする
        }
        //こういった感じでデフォルトの文言を変更
        Instabug.setValue("デバイスを振ることでフィードバックをどこからでも呼び出せます", forStringWithKey: kIBGLiveWelcomeMessageContent)
        //レポートする際にデータを添える
        Instabug.willSendReportHandler = { report in
            report.setUserAttribute(hoge, withKey: "hoge")
            return report
        }
    }
```
```swift
    //報告機能を呼び出してみる
    @IBAction func feedBackTappedButton(_ sender: Any) {
        BugReporting.invoke()
    }
```

##CI
###[CircleCI](https://circleci.com/build-environments/xcode/)
【１行で】
いわゆるCI(継続的インテグレーション)サービス

【もうちょっと解説】
「コミットしたら、自動でビルド・テストをしてSlackに通知」「○○ブランチにマージされたらFabricでβ版配信/AppStoreConenctにアップロード」とかができます（後者はFastlaneも登場するので、初めての場合は前者から取り組むといいと思います）。キャッシュも積極的に使って料金を抑えましょう。
ちなみに、[Bitrise](https://www.bitrise.io/features/ios-features)でも良いと思います（使いやすいGUIもあるので、iOSだけ考えるのであれば、Bitriseの方がはじめてのCIツールとしては良い気がする）。料金体系も違うので、実際にトライアルしてみて、使いやすいか料金的お得に使える方を選んでください。

##ABテスト
###[Firebase Remote Config](https://firebase.google.com/docs/remote-config/?hl=ja)
【１行で】
アプリのアップデートなしでコンソールから更新できるやつ

【もうちょっと解説】
用途としてはABテストだけでなく、強制アップデートバージョンをRemoteConfingで管理したり。リリースバージョンでユーザーに影響が出たら、強制アップデートを取り消せたりするので、とても便利です。最近CloudFunctionsにRemoteConfigトリガができて、リアルタイムで伝播させられるので、色々な使い方ができると思います。ジーズのFirebaseユーザーは是非使ってみてください。

【サンプル画像】
<img width="400" alt="Firebase Remote Config" src="https://qiita-image-store.s3.amazonaws.com/0/158756/4017dcef-87b8-82af-37af-240681b6b7dc.png">