Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ReRxSwift

84 views

Published on

Software-Architektur/-Design in der iOS-Entwicklung. In der traditionellen iOS-Entwicklung mit MVC (Model View Controller) oder heutzutage “trendigem” MVVM (Model View ViewModel) wird wenig bis keine Rücksicht auf den State (bzw. die Daten) in der App genommen. Das führt oft zu schwer verständlichem, und schlecht wartbarem Code, da alles undefiniert und quer verstreut in der App gemacht wird. Daher ist es essentiell, sich um die Organisation des States in der App zu kümmern. Um das Rad nicht neu zu erfinden, bedienen wir uns an Frameworks/Libraries wie ReSwift*, RxSwift** und die Verbindung der beiden “Technologien” über ReRxSwift***. Diese bieten ein gutes State-Management, was dazu führt, dass der State nur an einer Stelle in der App (im s.g. Store) verwaltet wird und nur kontrolliert (über s.g. Actions/Reducers) verändert werden kann. Über s.g. Subscriptions kann man den aktuellen Stand und Änderungen des States erfahren (z.B. in ViewControllers oder Views).

* Swift Implementierung von Redux (JavaScript)
** Swift Implementierung von reactiveX (für quasi jede populäre Programmiersprache verfügbar)
*** Swift Implementierung von react-redux (JavaScript)

Published in: Software
  • Be the first to comment

  • Be the first to like this

ReRxSwift

  1. 1. ReRxSwift or: how I learned to stop worrying and love the bomb state
  2. 2. MVC
  3. 3. model view view controller some data some fancy UI everything else
  4. 4. tab bar controller navigation controller label and button
  5. 5. tab bar controller view controller change data navigation controller view controller view controller navigation controller view controller view controller change data
  6. 6. state lives everywhere
  7. 7. multiple sources of truth
  8. 8. no straight forward sync mechanism
  9. 9. 😭
  10. 10. MVVM
  11. 11. …the savior?
  12. 12. 🤔
  13. 13. model view view controller some data some fancy UI everything else
  14. 14. view controller view model model view some data some fancy UI everything else view logic
  15. 15. view model did not solve any problems at all
  16. 16. we even introduced one more “source of truth”
  17. 17. …the savior?
  18. 18. NOPE
  19. 19. 😭
  20. 20. and now for something completely different
  21. 21. ReSwift (inspired by Redux)
  22. 22. action store w/ state reducers view* some data business logic fancy UI stuff *view = view + view controller subscribe dispatch change
  23. 23. action store w/ state reducers view* subscribe dispatch change *view = view + view controller
  24. 24. // define the store let store = Store<State>(reducer: reducer, state: nil) // define a state (important: value type) struct State: StateType { var data: String = "someData" }
  25. 25. action store w/ state reducers view* subscribe dispatch change *view = view + view controller
  26. 26. // define an action struct ChangeData: Action { let changedData: String } // create and dispatch an action let action = ChangeData(changedData: "changedData") store.dispatch(action)
  27. 27. action store w/ state reducers view* subscribe dispatch change *view = view + view controller
  28. 28. // reducer: action + state = new state func reducer(action: Action, state: State?) -> State { } *switch is non-exhausting for simplicity // create a new state if state is nil var state = state ?? State() // switch through desired actions switch action { case let action as ChangeData: } // perform state change state.data = action.changedData // return the new state return state
  29. 29. action store w/ state reducers view* subscribe dispatch change *view = view + view controller
  30. 30. class ReSwiftViewController: UIViewController, StoreSubscriber { @IBOutlet weak var button: UIButton! @IBOutlet weak var label: UILabel! } // subscribe to store func setup() { store.subscribe(self) } // receive state updates from store func newState(state: State) { self.label.text = state.data } // dispatch an action to store @IBAction func buttonTap(_ sender: Any) { let action = ChangeData(changedData: "changedData") store.dispatch(action) }
  31. 31. tab bar controller view controller navigation controller view controller view controller navigation controller view controller view controller store w/ state change data change data
  32. 32. real separation of state and view
  33. 33. one source of truth
  34. 34. unidirectional data flow
  35. 35. 😀
  36. 36. RxSwift (ReactiveX)
  37. 37. “the observer pattern done right”
  38. 38. event error completion time
  39. 39. // define data as a subject ("stream") let data = PublishSubject<String>() // subscribe to data data.asObservable() .subscribe(onNext: { string in print("data changed to: (string)") }) // bind data to label data.bind(to: label.rx.text) *disposing is left out for simplicity // trigger an update data.onNext("changedData")
  40. 40. very easy to “connect the dots”
  41. 41. just subscribe/bind
  42. 42. 😀
  43. 43. some math…
  44. 44. 😱
  45. 45. some math… very basic
  46. 46. ReSwift + RxSwift = ?
  47. 47. 🤔
  48. 48. ReRxSwift(inspired by react-redux)
  49. 49. actions store w/ states reducers view* *view = view + view controller
  50. 50. ViewReRxSwift “Connection” ReSwift actions store w/ states reducers view* *view = view + view controller actions props
  51. 51. ViewReRxSwift “Connection” ReSwift actions store w/ states reducers view* actions props *view = view + view controller
  52. 52. // define props extension ReRxSwiftViewController: Connectable { } struct Props { let data: String } // state to props mapping private let mapStateToProps = { (state: State) in } return ReRxSwiftViewController.Props( data: state.data )
  53. 53. ViewReRxSwift “Connection” ReSwift actions store w/ states reducers view* actions props *view = view + view controller
  54. 54. // define actions extension ReRxSwiftViewController: Connectable { } struct Actions { let changeData: (String) -> Void } // dispatch to actions mapping private let mapDispatchToActions = { (dispatch: @escaping DispatchFunction) in } return ReRxSwiftViewController.Actions( changeData: { dispatch(ChangeData(changedData: $0)) } )
  55. 55. ViewReRxSwift “Connection” ReSwift actions store w/ states reducers view* actions props *view = view + view controller
  56. 56. class ReRxSwiftViewController: UIViewController { @IBOutlet weak var button: UIButton! @IBOutlet weak var label: UILabel! } // set up connection with store and mappings let connection = Connection(store: store, mapStateToProps: mapStateToProps, mapDispatchToActions: mapDispatchToActions) // establish connection and bind to a label func setup() { self.connection.connect() self.connection.bind(Props.data, to: self.label.rx.text) } // dispatch an action
 @IBAction func buttonTap(_ sender: Any) { self.connection.actions.changeData("changedData") }
  57. 57. even better separation of concerns
  58. 58. easy to understand
  59. 59. easy to re-use and unit-test
  60. 60. 🤩
  61. 61. at a glance
  62. 62. fail safe state handling
  63. 63. unidirectional data flow
  64. 64. UI bindings
  65. 65. credits
  66. 66. github.com/ReSwift/ReSwift github.com/ReactiveX/RxSwift github.com/svdo/ReRxSwift hackernoon.com/thinking-in-redux-when-all-youve-known-is-mvc-c78a74d35133 gist.github.com/staltz/868e7e9bc2a7b8c1f754 rxmarbles.com swifting.io/blog/2016/09/07/architecture-wars-a-new-hope khanlou.com/2014/03/model-view-whatever sharpfivesoftware.com/2016/07/20/mvvm-is-lipstick-on-a-pig themetapicture.com/the-life-of-a-software-engineer https://en.wikipedia.org/wiki/LOLCODE
  67. 67. questions?
  68. 68. KTHXBYE

×