Youtubeのサムネイルを検索できるアプリをリリースしました！

##はじめに簡単な自己紹介✍️
主にiOS開発をメインに勉強しております、私立文系の凡人大学生です、、、😇
今年の目標は応用情報技術者試験に受かることです〜！

##リリースしたアプリ📱

![YoutubeGif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302458/7ba2705a-e4c1-453b-a6c9-1162b725cf3b.gif)


Youtubeのサムネイルを検索できるアプリになっています。

App Store
https://apps.apple.com/jp/app/%E5%8B%95%E7%94%BB%E5%88%86%E6%9E%90/id1502014149

GitHub
https://github.com/geekshu625/YoutubeAPI
（改善点あればプルリクとか貰えますと泣いて喜びます）



##なぜ作ったか？🤔
###Youtubeのサムネイルを検索できるプラットフォームがない

最近、僕の友人にもYoutuberになる人が現れ、様々なツールやプラットフォームを駆使することで簡単に高クオリティの動画を制作できる時代になってきました。
僕自身はただの視聴者で、暇さえあればみてしまう中毒者です🤐
実際にYoutubeを見ている人はわかると思うのですが、動画を「見たい」か「見たくない」かはほぼ**サムネイル**で選択していていると思います。
ですのでサムネイルを製作することは本編動画を作成するのとほぼ同等の重要性を持っていると考えられます。
では、実際に再生数を伸ばすサムネイルをどうやって作っているのかというと、再生数と好評価が多い動画のサムネイルを真似て作るらしいのです。
それらの条件にあったサムネイルをYoutubeで探すとなると、一覧で再生数はわかっても好評価は動画を開かないと見れず煩わしい仕様になっていることに気づきます。
それらの悩みをYoutuberから聞き、
「じゃあサムネイルに特化したプロットフォームを使ったら、、、」と思ったら１つもないことに気づきました。
その経緯があり、頻繁に使いたいからアプリで！ってことで作り始めました。

##開発期間📆
しっかり取り掛かり始めたのが、今年に入ってからなので
2ヶ月弱ぐらいでメインの機能のみを作ってみました。

##使用した技術🔨

今回の開発にあたって技術的に課題としたのがRxSwift+MVVVMです。
技術書店で買った書籍や尊敬する方々の記事を参考にさせて頂きました（以下でまとめています）

```swift
// -- API通信の一部
// Observable化したAPIレスポンスを返す
    static func thubnailRequest(searchText: String, nextPageToken: String) -> Observable<ThubnailRooter> {
        let baseUrl = APIEndpoint.thubnailURL(searchText: searchText, nextPageToken: nextPageToken)
        let url = URL(string: baseUrl)
        
        return Observable.create { observer -> Disposable in
            Alamofire.request(url!).response { (response) in
                guard let data = response.data else { return }
                do {
                    if let errorModel = try? JSONDecoder().decode(APIErrorRooter.self, from: data) {
                        let apierror = YoutubeAPIError.init(errorCode: errorModel.error.code)
                        observer.onError(apierror)
                    }
                    let model = try JSONDecoder().decode(ThubnailRooter.self, from: data)
                    observer.onNext(model)
                    observer.onCompleted()
                } catch {
                    let connectingError = ConnectionError(errorCode: error._code)
                    observer.on(.error(connectingError))
                }
            }
             return Disposables.create()
        }
    }
```
Swiftの実践的な書き方がまだまだ身についていないことを自覚しており、自分が完全に理解できるコードのみで実装しました
（ジェネリクスなどをうまく活用してリファクタリングできる箇所がまだまだありますね、、、）
これまでMVCで構築することが多く、ロジックを分轄しても<font color="Red">**FatViewController**</font>になりがちで嫌気が指していました。
なので今回はMVVMを採用し、データバインディングにRxを用いることで処理の分担がスッキリさせることを意識しました。
しかし、まだまだRxの勉強は途中で悩む場面も多々ありました😭
またUnit TestもAPI通信周り（Model）だけしかできていないのでUnit Test周辺も勉強していきたいです。

その他の技術としては、デプロイ：fastlane、証明書管理：fastlane-match、ビルド：Xcodegenを導入しました。
CI/CD系も以後導入していきたいです。


## 今回の開発を通して

今回の技術的なテーマであったRxSwiftですが、実用するのに難しい場面がたくさんありました、、、
記事や本を読んで理解したつもりでも、「いざ実践！」ってなった場合には「🧐？？」となることが多かったです。
またSwiftの書き方もまだまだなので、コーディングする機会を増やして知見を貯めていければなっと思ってます。


## 参考文献

基本的なRxSwiftについて
・[RxSwift研究読本1 入門編](https://booth.pm/ja/items/1076262)
・[比較して学ぶRxSwift入門](https://booth.pm/ja/items/1314164)

設計や実践的な使い方・記事構成
・[あとで読むQiitaリーダーアプリをリリースしました](https://qiita.com/hirothings/items/78493363df04e5f31d25)


## 今後追加していく機能

- [ ] いいね機能
- [ ] analyticsでサムネイル人気の統計図る
- [ ] 初期画面にジャンルタブバー設置
- [ ] リファクタリング
etc...