20200326のiOSに関する記事は3件です。

[RxSwift]RxSwiftとは

RxSwiftとは

コードが新しいデータに反応、順次的に分離された方式で処理される、非同期プログラム開発が簡素化できる、データの変化に対応しやすい。
observable asynchronous functional via schedulers

RxSwiftの基礎

Rxの3つの構成要素についてみてみる
Observables、Operators、Schedulers

1.Observables

  • Observable クラスはRxの基盤
  • Tタイプのデータを渡す、イベントを非同期に生成
    • 他のクラスでemit(放出?)する値を購読できるようにする
  • ObservableTypeのProtocol(Observable)はシンプルで、以下の3つのイベントのみemitし、observersはこの3つのみ受信できる
    • next:最新/次のデータを渡すイベント
    • completed:成功的にイベントを終了させるイベント。追加イベント生成しない
    • error:Observableがエラー発生。追加イベント生成しない

Finite Observable Sequences (有限の観測可能なシーケンス)

例えば、ファイルをダウンロードするコードをイメージ
流れは
1. ファイルのダウンロードが始まって、データを監視する
2. 続けてファイルをダウンロードする
3. (エラーの場合)ネットワークが切れたらエラーになって停止する
4. (成功した場合)問題なくダウンロードが成功する

API.download(file: "https://www...")
    .subscribe(onNext: { data in
        ... append data to temporary file
    },
    onError: { error in 
        ... display error to user
    },
    onCompleted: {
        ... use downloaded file
    })
  • API.downloadはダウンロードするデータObservable<Data>インスタンスをreturn
  • onNextクロージャでnextイベントを受け取ることができる。
  • onErrorクロージャではerrorイベントが受け取れる。
  • 最終的にはonCompletedクロージャでcompletedイベントを受け取る

Infinite Observable Sequences(無限の観測可能なシーケンス)

ダウンロードのように自然に終了するものとは異なって、無限なsequenceがある。例えばUIイベントなどは無限に観測できる。
例えば、デバイスの横/縦モードに反応するコードをイメージ
流れは
1. UIDeviceOrientationDidChange observerを追加
2. 方向転換が管理できるcallback methodが必要
3. UIDeviceの現在の方向を確認して、画面に表示する
4. 方向転換ができるデバイスが存在する以上、自然に終了することはない
5. 無限なsequenceなので一応初期値が必要

UIDevice.rx.orientation
    .subscribe(onNext: { current in
        switch current {
            case .landscape:
                ... re-arrange UI for landscape
            case .portrait:
                ... re-arrange UI for portrait
        }
    })
  • ここでは、onErroronCompletedは発生しないはずなので、記述も不要

2. Operators

  • ObservableTypeObservableクラスはより複雑な論理を実現するためにたくさんのメソッドが含まれている。それらをOperatorを呼ぶ
  • Operatorは非同期入力を受けて出力のみ生成するだけで、複数のOperatorを併せて使うことができる
    • Observableに、より入ってきたのを処理して放出?する役割

コードを見た方が分かりやすいかも

UIDevice.rx.orientation
  .filter { value in
    return value != .landscape
  }
  .map { _ in
    return "Only Portrait"
  }
  .subscribe(onNext: { string in
    showAlert(string)
  })
  • 上記でみると分かるように filter.landscapeではないものだけ、return
  • .portraitの場合はmapに入るはずで、mapではStringに変換してreturn
  • 最後にsubscribeでは結果としてstringをshowAlertメソッドで表示している

このように複数のOperatorを使って、いろんなことができる。

3.Schedulers

  • SchedulersはRxではdispatch queueと同じだが、もっと使いやすくて強力
  • RxSwiftではいろんなスクジューラーが既に定義されている。99%の状況で使えるので、開発者が自分だけのスケジューラーを生成することはない DOqRvva.png

RxCocoa

RxSwiftは一般的なRx APIで、Cocoaとか特定のUIKitクラスについて何の情報も持たない。RxCocoaはRxSwiftと一緒に使われながら、UIKitやCocoaフレームワーク基盤開発をサポートする全てのクラスを持っているらしい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[RxSwift] RxSwiftとは

RxSwiftとは

コードが新しいデータに反応、順次的に分離された方式で処理される、非同期プログラム開発が簡素化できる、データの変化に対応しやすい。
observable asynchronous functional via schedulers

RxSwiftの基礎

Rxの3つの構成要素についてみてみる
Observables、Operators、Schedulers

1.Observables

  • Observable クラスはRxの基盤
  • Tタイプのデータを渡す、イベントを非同期に生成
    • 他のクラスでemit(放出?)する値を購読できるようにする
  • ObservableTypeのProtocol(Observable)はシンプルで、以下の3つのイベントのみemitし、observersはこの3つのみ受信できる
    • next:最新/次のデータを渡すイベント
    • completed:成功的にイベントを終了させるイベント。追加イベント生成しない
    • error:Observableがエラー発生。追加イベント生成しない

Finite Observable Sequences (有限の観測可能なシーケンス)

例えば、ファイルをダウンロードするコードをイメージ
流れは
1. ファイルのダウンロードが始まって、データを監視する
2. 続けてファイルをダウンロードする
3. (エラーの場合)ネットワークが切れたらエラーになって停止する
4. (成功した場合)問題なくダウンロードが成功する

API.download(file: "https://www...")
    .subscribe(onNext: { data in
        ... append data to temporary file
    },
    onError: { error in 
        ... display error to user
    },
    onCompleted: {
        ... use downloaded file
    })
  • API.downloadはダウンロードするデータObservable<Data>インスタンスをreturn
  • onNextクロージャでnextイベントを受け取ることができる。
  • onErrorクロージャではerrorイベントが受け取れる。
  • 最終的にはonCompletedクロージャでcompletedイベントを受け取る

Infinite Observable Sequences(無限の観測可能なシーケンス)

ダウンロードのように自然に終了するものとは異なって、無限なsequenceがある。例えばUIイベントなどは無限に観測できる。
例えば、デバイスの横/縦モードに反応するコードをイメージ
流れは
1. UIDeviceOrientationDidChange observerを追加
2. 方向転換が管理できるcallback methodが必要
3. UIDeviceの現在の方向を確認して、画面に表示する
4. 方向転換ができるデバイスが存在する以上、自然に終了することはない
5. 無限なsequenceなので一応初期値が必要

UIDevice.rx.orientation
    .subscribe(onNext: { current in
        switch current {
            case .landscape:
                ... re-arrange UI for landscape
            case .portrait:
                ... re-arrange UI for portrait
        }
    })
  • ここでは、onErroronCompletedは発生しないはずなので、記述も不要

2. Operators

  • ObservableTypeObservableクラスはより複雑な論理を実現するためにたくさんのメソッドが含まれている。それらをOperatorを呼ぶ
  • Operatorは非同期入力を受けて出力のみ生成するだけで、複数のOperatorを併せて使うことができる
    • Observableに、より入ってきたのを処理して放出?する役割

コードを見た方が分かりやすいかも

UIDevice.rx.orientation
  .filter { value in
    return value != .landscape
  }
  .map { _ in
    return "Only Portrait"
  }
  .subscribe(onNext: { string in
    showAlert(string)
  })
  • 上記でみると分かるように filter.landscapeではないものだけ、return
  • .portraitの場合はmapに入るはずで、mapではStringに変換してreturn
  • 最後にsubscribeでは結果としてstringをshowAlertメソッドで表示している

このように複数のOperatorを使って、いろんなことができる。

3.Schedulers

  • SchedulersはRxではdispatch queueと同じだが、もっと使いやすくて強力
  • RxSwiftではいろんなスクジューラーが既に定義されている。99%の状況で使えるので、開発者が自分だけのスケジューラーを生成することはない DOqRvva.png

RxCocoa

RxSwiftは一般的なRx APIで、Cocoaとか特定のUIKitクラスについて何の情報も持たない。RxCocoaはRxSwiftと一緒に使われながら、UIKitやCocoaフレームワーク基盤開発をサポートする全てのクラスを持っているらしい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

はじめに簡単な自己紹介✍️

主にiOS開発をメインに勉強しております、私立文系の凡人大学生です、、、😇
今年の目標は応用情報技術者試験に受かることです〜!

リリースしたアプリ📱

YoutubeGif.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から聞き、
「じゃあサムネイルに特化したプロットフォームを使ったら、、、」と思ったら1つもないことに気づきました。
その経緯があり、頻繁に使いたいからアプリで!ってことで作り始めました。

開発期間📆

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

使用した技術🔨

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

// -- 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で構築することが多く、ロジックを分轄してもFatViewControllerになりがちで嫌気が指していました。
なので今回はMVVMを採用し、データバインディングにRxを用いることで処理の分担がスッキリさせることを意識しました。
しかし、まだまだRxの勉強は途中で悩む場面も多々ありました😭
またUnit TestもAPI通信周り(Model)だけしかできていないのでUnit Test周辺も勉強していきたいです。

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

今回の開発を通して

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

参考文献

基本的なRxSwiftについて
RxSwift研究読本1 入門編
比較して学ぶRxSwift入門

設計や実践的な使い方・記事構成
あとで読むQiitaリーダーアプリをリリースしました

今後追加していく機能

  • いいね機能
  • analyticsでサムネイル人気の統計図る
  • 初期画面にジャンルタブバー設置
  • リファクタリング etc...
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む