ページ

2018年3月1日木曜日

ReduxのSwift実装「ReSwift」を触ってみる

ReSwift

:computer:環境構築


:eyes: 概要


  • アプリケーション全体の状態(State)はツリーの形で1つのオブジェクトで作られ、1つのストアに保存される
  • 状態を変更する手段は、変更内容をもったactionオブジェクトを発行して実行するだけ
  • アクションがどのように状態を変更するかを「Reducer」で行う

Reduxの登場人物

  • Store
    • アプリ内で1個、1つの状態(State)を保持
    • StateへアクセスするためのgetState()を提供する
    • Stateを更新するためのdispatch(action)を提供する
    • リスナーを登録するためのsubscribe(listener)を提供する
  • State
    • アプリケーションの状態を表す
  • Action
    • Storeが保持しているStateの変更内容が記載されているオブジェクト
    • Actionはstore.dispatch()でStoreへ送られる (dispatch: 発信、急送、派遣の意味)
  • ActionCreator
    • Actionを作成する
  • Reducer
    • ActionとStateから、新しいStateを作成して返す
    • Stateを更新することはせず、新しいStateのオブジェクトを作成して返す

:pencil: 実装


簡単なサンプル

超ミニマム実装をやってみます。
  • State
    AppState.swift
    struct AppState: StateType {
        var text: String?
    }
    
  • Action
    InputAction.swift
    struct InputAction: Action {
        var text: String
    }
    
  • Reducer
    AppReducer.swift
    import ReSwift
    
    func AppReducer(action: Action, state: AppState?) -> AppState {
        let state = state ?? AppState(text: "")
        var newState = state
        switch action {
        case _ as InputAction:
            newState = AppState(text: (action as! InputAction).text)
        default:
            break
        }
        return newState
    }
    
  • ViewController
    ViewController.swift
    import UIKit
    import ReSwift
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            appStore.subscribe(self)
        }
    
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            // 監視削除
            appStore.unsubscribe(self)
        }
    
        @IBAction func onPush(_ sender: Any) {
            var text = appStore.state.text ?? ""
            text = text + "a"
            appStore.dispatch(InputAction(text: text))
        }
    }
    
    extension ViewController: StoreSubscriber {
        typealias StoreSubscriberStateType = AppState
    
        func newState(state: AppState) {
            print(state.text ?? "")
        }
    }
    
  • AppDelegate
    AppDeledate.swift
    import UIKit
    import ReSwift
    
    // アプリで1つのStoreを作成する ←追加
    let appStore = Store(reducer: AppReducer, state: AppState())
    

動作確認

動作自体はただボタンを押したら"a"が追加されてデバッグログに吐かれるというものです。
image.png (9.9 kB)

0 件のコメント:

コメントを投稿