概要
Swiftでreduxを実現するならReSwiftというパッケージが良いらしいです。
サンプルをクローン
下記が公式のカウンターアプリです。 コードを見てみます。 github.com
ディレクトリ構成
下記のような構成です。
- Reducers - Actions - State AppDelegate ViewController
State
状態の構造体を定義する場所
import ReSwift struct AppState: StateType { var counter: Int = 0 }
Actions
Actionを定義する場所。同一ファイルに全部まとめる
import ReSwift // all of the actions that can be applied to the state struct CounterActionIncrease: Action {} struct CounterActionDecrease: Action {}
Reducers
reducerを定義する場所。(ReducerとはActionとStateを受け取って、処理をまとめる場所)
import ReSwift // the reducer is responsible for evolving the application state based // on the actions it receives func counterReducer(action: Action, state: AppState?) -> AppState { // if no state has been provided, create the default state var state = state ?? AppState() switch action { case _ as CounterActionIncrease: state.counter += 1 case _ as CounterActionDecrease: state.counter -= 1 default: break } return state }
AppDelegate
AppDelegateがまだキャッチアップできていないものの、起動時の時だけmainStoreをインスタンス化してGlobalに扱ってるっぽい。。?
import UIKit import ReSwift // The global application store, which is responsible for managing the appliction state. let mainStore = Store<AppState>( reducer: counterReducer, state: nil ) @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { return true } }
ViewController
ViewとStoreを紐づけたり、UIアクションと処理を紐づけたりしているっぽい
import UIKit import ReSwift class ViewController: UIViewController, StoreSubscriber { typealias StoreSubscriberStateType = AppState @IBOutlet weak var counterLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // subscribe to state changes mainStore.subscribe(self) } func newState(state: AppState) { // when the state changes, the UI is updated to reflect the current state counterLabel.text = "\(mainStore.state.counter)" } // when either button is tapped, an action is dispatched to the store // in order to update the application state @IBAction func downTouch(_ sender: AnyObject) { mainStore.dispatch(CounterActionDecrease()); } @IBAction func upTouch(_ sender: AnyObject) { mainStore.dispatch(CounterActionIncrease()); } }
まとめ
SwiftUIと組み合わせて使えるものだと期待していたけれど、そういうわけではなさそう。。 Storyboardぽちぽちはあまり得意ではないのでなんとかSwiftUIに慣れていきたい。