約2年のiOSアプリ開発で実際に使ったライブラリとそこから得られた知見


会社で約2年ほどiOSアプリを新規で開発してきた中で実際に用いたライブラリや検討したもの、または参考にして独自に作ったものなどを紹介します。

##動画撮影・編集アプリ(開発言語: Objective-Cで用いたもの)
・[GPUImage](https://github.com/BradLarson/GPUImage)
ド定番。カメラ処理やフィルターなど全般で活用。

・[KLCPopup](https://github.com/jmascia/KLCPopup)
ポップアップのライブラリです。showTypeとdismissTypeを指定できるので自分好みなアニメーションを選択できます。

・[ReverseClip](https://github.com/mikaelhellqvist/ReverseClip)
動画の逆再生部分で用いています。

・[SDAVAssetExportSession](https://github.com/rs/SDAVAssetExportSession)
AVAssetExportSessionを使いやすくしたもの

・[iso-8601-date-formatter](https://github.com/boredzo/iso-8601-date-formatter)
NSDateFormatterのサブクラス。日時のフォーマットなどを扱う際に便利です。

・[SimpleKeychain](https://github.com/auth0/SimpleKeychain)
キーチェーンを扱うラッパーです。

##女性向け美容アプリ(開発言語: Objective-C)で用いたもの

・[SSZipArchive](https://github.com/ZipArchive/ZipArchive)
アプリが通信容量を削減するためニュース記事をZip形式で受け取っており、それを解凍するためにこちらのライブラリを使いました。パスコード付きのものも対応しています。

・[MBProgressHUD](https://github.com/jdg/MBProgressHUD)
言わずもがなの有名ライブラリ。
HUDのタイプを指定できます。個人的にはDLなどの進捗を表す際に使うと便利だと思います。
その他の用途ならSVProgressHUDが個人的に好きです。MBProgressHUDはコードも割と書かなきゃいけないので。

・[SDWebImage](https://github.com/rs/SDWebImage)
こちらも言わずもがなですね。
簡単に非同期で画像ダウンロードもできキャッシュも上手くやってくれるライブラリ。
画像ダウンロードが完了するまでに表示するplaceHolder画像が設定できたりします。

###以下参考にしたもの
・[NSDate-Extensions](https://github.com/erica/NSDate-Extensions)
アプリ内にアラームやカレンダーの機能があるので日付の計算や時間の計算を簡単にしたいという思いで、独自のNSDateのカテゴリを作るときに非常に参考になりました。

``` Objective-C 
#define D_MINUTE	60
#define D_HOUR		3600
#define D_DAY		86400
#define D_WEEK		604800
#define D_YEAR		31556926

//例
+ (NSDate *) dateTomorrow;
+ (NSDate *) dateYesterday;
- (NSDate *) dateByAddingYears: (NSInteger) dYears;
- (NSDate *) dateBySubtractingYears: (NSInteger) dYears;
```

・[RDVCalendarView](https://github.com/robbdimitrov/RDVCalendarView)
カレンダーを作るときに参考にしました。こちらをそのまま使おうとするとページング対応してないので、月を変えるときにボタンでviewをリフレッシュするか、UISwipeGestureなどを使ってスワイプの際にCATransitionのアニメーションなどでそれらしくするかになってしまいます。ページングのUXを提供したい場合は普通にUICollectionViewで作るのがいいと思います。

【番外編】
[iOS開発におけるウィンドウ「UIWindow」の知られざる活用方法とは？](https://codeiq.jp/magazine/2014/05/9493/)
アプリ内で様々なポップアップを出しているのですがその時にこちらの記事を参考にさせていただいた記憶があります。

##GIFアプリ(開発言語: Objective-C)で用いたもの
- 日本で流行っているGIFを閲覧できたり実際にカメラロールの動画をGifに変換できたりとにかくGIFつくしのアプリ

Gifの表示をUIImageViewの要領で扱うことのできるライブラリです.
・[FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage)
・[YLGifImage](https://github.com/liyong03/YLGIFImage)


この２つのうちどちらを採用するかで悩みましたが、commit率やcontributorの数などからFLAnimatedImageを採用しました。
そもそもGifって何？iOSが提供しているUIImageViewのアニメーションってどういう仕組みだっけ？っていうのをこちらの記事が噛み砕いているのでオススメです。
Gifのスピードを変えたり逆再生やシャッフルなどの機能を実装する時に知識として非常に参考になりました。

http://engineering.flipboard.com/2014/05/animated-gif/

・[ZFModalTransitionAnimator](https://github.com/zoonooz/ZFDragableModalTransition)
通常のModalやPushの画面遷移より少しリッチなアニメーションが実現できたりします。

このライブラリを使う際に
`UIViewControllerTransitioningDelegate`
`UIViewControllerAnimatedTransitioning`
について調べたことでカスタム画面遷移に強くなれた気がします。自分で好きなアニメーションを作りたいって方には中を見るのはオススメです。

・[GIFConverter](https://github.com/n1mda/gif2mp4)
GIFを.MP4形式に変換してくれます。その際にスピードも調節できたりします。

・[ASValueTrackingSlider](https://github.com/alskipp/ASValueTrackingSlider)
UISliderの上にポップアップを付随させるライブラリ。相当便利でした。
CMPopTipViewとの組み合わせでカスタム作った方が汎用性はある気がします。

・[RNBlurModalView](https://github.com/rnystrom/RNBlurModalView)
お洒落。画像保存などした際に表示していました。

・[WYPopoverController](https://github.com/nicolaschengdev/WYPopoverController)
Popoverの表示に便利

・[YapGif](https://github.com/amacou/YAPGif)
スターは少ないですが複数枚のUIImageからGifを作り出すのに結構便利
[参考]
[iOS用のアニメーションgifライブラリYAPGif作った](http://blog.amacou.net/post/76313738829/ios%E7%94%A8%E3%81%AE%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3gif%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AAyapgif%E4%BD%9C%E3%81%A3%E3%81%9F)

・[AFNetworking](https://github.com/AFNetworking/AFNetworking, "AFNetworking")
言わずもがなの有名通信系ライブラリ

###以下参考にしたもの
・[RMPZoomTransitionAnimator](https://github.com/recruit-mp/RMPZoomTransitionAnimator)
初期のUIでGifをタップしたら浮き上がらせて画面遷移するアニメーションを実装しており、当時このライブラリを参考にしてカスタムを作っていました。オススメです。
こちらも先に述べた
`UIViewControllerTransitioningDelegate`
`UIViewControllerAnimatedTransitioning`
を理解しておいたほうが読みやすいと思います。

・[WaterfallLayout](https://github.com/chiahsien/CHTCollectionViewWaterfallLayout, "WaterfallLayout")
PinterstのようなUIを実現するのに採用。しっかり読めば```UICollectionViewFlowLayout```の基礎が身につくんじゃないかと。

##動画プラットフォームアプリ(開発言語: Swift)で用いたもの
気軽に動画投稿ができ他のユーザーとアプリ内でコミュニケーションがとれるアプリです。

・[SweetAlert](https://github.com/codestergit/SweetAlert-iOS)
Swift製のお洒落なアラート。
タイプはSuccess,Error,Warning,Noneの他にCustomの画像も対応しています.

今まではポップアップやアラートを作る時にUIWindowを継承したBaseWindowを作ってさらにそれを継承した・・・って感じの構成にしてたのですがSweetAlertの中を見てからkeyWindowを取得してviewをはりつけてアニメーションさせるって構成に変えました。まあやってること自体はそんなに変わらないのですが。

・[KingFisher](https://github.com/onevcat/Kingfisher)
Swiftで書かれた画像ダウンロードライブラリ。個人的にSDWebImageより使いやすいです。純正Swiftってところもいい。


・[SVProgressHUD](https://github.com/SVProgressHUD/SVProgressHUD)
言わずもがなのHUDライブラリ。MBProgressHUDよりこっちの方がアプリデザインに合っていたから採用した。

・[PureLayout](https://github.com/PureLayout/PureLayout)
AutoLayoutをシンプルなコードで書けるライブラリ。一度慣れると相当使いやすくオススメです。
使っているうちに頭の中で何となくviewの位置関係が想像できるようになります。
UITableViewAutomaticDimensionと合わせて使えば可変のCellなども簡単です。

``` Swift
    override func updateConstraints() {
        if alreadySetupConstraints == false {
 
            authorImage.autoSetDimensionsToSize(CGSizeMake(42, 42))
            authorImage.autoPinEdgeToSuperviewEdge(.Top, withInset: 16)
            authorImage.autoPinEdgeToSuperviewEdge(.Leading, withInset: 16)
            authorImage.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 16, relation: .GreaterThanOrEqual)
            
            authorLabel.autoPinEdgeToSuperviewEdge(.Top, withInset: 17.5)
            authorLabel.autoPinEdge(.Leading, toEdge: .Trailing, ofView: commentIconImage, withOffset: 8)
            authorLabel.autoPinEdge(.Trailing, toEdge: .Leading, ofView: dateLabel, withOffset: 7, relation: .GreaterThanOrEqual)
            
            commentLabel.autoPinEdge(.Leading, toEdge: .Trailing, ofView: commentIconImage, withOffset: 10)
            commentLabel.autoPinEdge(.Top, toEdge: .Bottom, ofView: authorLabel, withOffset: 7)
            commentLabel.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 12, relation: .GreaterThanOrEqual)
            commentLabel.autoPinEdgeToSuperviewEdge(.Trailing, withInset: 40)
            

            commentIconImage.autoSetDimensionsToSize(CGSizeMake(12, 11))
            commentIconImage.autoPinEdgeToSuperviewEdge(.Top, withInset: 21)
            commentIconImage.autoPinEdge(.Leading, toEdge: .Trailing, ofView: authorImage, withOffset: 16)
            
            dateLabel.autoPinEdgeToSuperviewEdge(.Right, withInset: 15)
            dateLabel.autoPinEdge(.Top, toEdge: .Top, ofView: authorLabel)
            alreadySetupConstraints = true
        }
        super.updateConstraints()
    }
```

上記はUICollectionViewCell内の実装の例ですが.GreaterThanOrEqualのように可変ということを直感的に書けるのは個人的にわかりやすくて好きです。

他の候補
・[Cartography](https://github.com/robb/Cartography)
・[SnapKit](https://github.com/SnapKit/SnapKit)

・[TSMessage](https://github.com/KrauseFx/TSMessages)
画面上部への通知を簡単に実装できます。
デザイン変更などもファイルで用意されているTSMessagesDegaultDesign.jsonを編集するのみ。

・[LockSmith](https://github.com/matthewpalmer/Locksmith)
キーチェーンを簡単に扱えるラッパー。
他の候補
[KeychainAccess](https://github.com/kishikawakatsumi/KeychainAccess)

・[JTSImageViewController](https://github.com/jaredsinclair/JTSImageViewController)
Slackアプリを使っているユーザーには馴染みがあるような画像拡大のアニメーションライブラリです。
筆者がSlack好きなので採用しました.

・[Alamofire](https://github.com/Alamofire/Alamofire)
AFNetworkingのSwift版ですね。Boltsと組みわせて使っています。

・[Bolts]()
非同期処理を直列で書くことができるものです。
[参考記事]
[Bolts-iOSのとっても簡単な使い方説明](http://qiita.com/morizotter/items/8fcd8017b938927f6c4a)

###以下参考にしたもの
・[SECoreTextView](https://github.com/kishikawakatsumi/SECoreTextView)
ハッシュタグやリンク(https://〜)などにタップ判定をつけてアクションを起こすときの参考になりました。
NSRegularExpressionなどと組み合わせると独自のリンクが作れます。
[参考記事]
・[UITextViewでタップ可能なリンクをカスタマイズする](http://blog.kishikawakatsumi.com/entry/20130605/1370370925, "UITextViewでタップ可能なリンクをカスタマイズする")

・[Chorister](https://github.com/katryo/Chorister)
Choristerは音楽ファイルを再生しながらキャッシュにいれるライブラリなのですが、アプリ内ではこちらを参考に動画ファイルを再生しながらキャッシュにいれるという実装をしました。
```AVAssetResourceLoader```を使ったことがなかったため新鮮でした。
[参考記事]
・[iOSアプリでWeb上の音楽ファイルをHTTPストリーミング再生しながらキャッシュにも入れるライブラリ、Choristerとその実装](http://qiita.com/katryo/items/c152ea9de11edbdbc0e4)
・[AVPlayerCaching](https://gist.github.com/anonymous/83a93746d1ea52e9d23f)

・[DXPopOver](https://github.com/xiekw2010/DXPopover)
CMPopTipViewに用途は近いです。Swiftに書き換えて使いました。
```UIBezierPath```の勉強がてら。

##動画編集アプリ(開発言語: Swift)で用いたもの
・[CMPopTipView](https://github.com/chrismiles/CMPopTipView)
UINavigationBarButtonIやUIButtonなどを押した際にミニポップアップを表示できる。

・[GPUImage](https://github.com/BradLarson/GPUImage)
前述。

###以下参考にしたもの
・[RAReorderableLayout](https://github.com/ra1028/RAReorderableLayout)
UICollectionViewのスクロール方向がVerticalのみでHorizontalはサポートされていなかったので実装には用いませんでしたが非常に参考になりました。

わりとヘビーなアプリなのですが、ライブラリはあまり用いておらずAVFoundation周りをゴリゴリって感じでした。
これについてはライブラリというより各APIとかの紹介したほうが良さそうって思いました。

余談ですが
[firefox-ios](https://github.com/mozilla/firefox-ios)のiOSアプリがソースコードを全て公開してるんですがSwiftの勉強に非常にオススメです。
凝った書き方だったりSwiftらしさを味わえるんじゃないかなーと。

``` Swift
public class KeyboardHelper: NSObject {
    public var currentState: KeyboardState?

    private var delegates = [WeakKeyboardDelegate]()

    public class var defaultHelper: KeyboardHelper {
        struct Singleton {
            static let instance = KeyboardHelper()
        }
        return Singleton.instance
    }

    /**
     * Starts monitoring the keyboard state.
     */
    public func startObserving() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "SELkeyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "SELkeyboardDidShow:", name: UIKeyboardDidShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "SELkeyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
    }

    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
``` 
特にこのKeboardHelperなどの考えは非常に参考になりました。
詳しくは中を見てみてください。


##ライブラリを探すコツ
① とりあえずGitHubの有名どころをStar順にざーっと上から見たら大体のものは抑えられるかと。
②　[COCOAPODS SEARCH](http://cocoapods.wantedly.com/)を見る
③  [Trending in open source](https://github.com/trending/swift)のSwiftタグのものを見る
検索条件はtodayだったり, weeklyだったり選べます。
④ 参考にしたい動きなどを実現しているアプリの設定画面からライセンスを見る。
それなりの規模のアプリであれば割と使っているライブラリを載せています。
⑤ GitHubのCode検索
<img width="240" alt="スクリーンショット 2016-04-14 10.46.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/66235/b9825d9f-4404-b53d-23dd-bfe3b33854f5.png">
ライブラリとは少し違いますが、使いたいAPIのメソッドなどで検索するとヒットするので実際に使い方を見たりするのも参考になります。

##終わりに
自分で大体作れるようになってくるにしたがってUI系などはライブラリを使うことが少なくなったなという印象です。

昔のソースコード見るのがわりと面白かったです。命名方法などは特に変わっていませんが、インデントルール守ってなかったり同じ(ような)コード大量にあったり分離が微妙だったり、さすがに成長してるなーと実感できました。

ライブラリの使い方は分かっても、どういう風に作られているのかを理解しないと、応用が利かないエンジニアになってしまうと個人的に考えています。
ですので、最近は中を見てから自分なりに書き換えて使ったり(Objective-C製のものをSwiftへ)知らないAPIなどについては調べてから使うようにしています。勿論時間も勿体ないので規模感にもよりますが・・。

あるライブラリを使う → 次から同じようなライブラリを自分で作れるようになろう
くらいの気持ちでいたようないい気がします。