This document discusses several iOS architecture patterns including MV(x), VIPER, VIP (Clean Swift), and Redux. It provides an overview of each pattern, including their key components like models, views, and controllers. It also summarizes the core principles of Redux as having a single source of truth for state, read-only state changes via pure functions, and examples of how actions, reducers, and middleware are used to manage state changes in a predictable way. Sample code links are provided for several of the patterns discussed.
Convert to study guideBETA
Transform any presentation into a summarized study guide, highlighting the most important points and key insights.
3. What is a good architecture ?
1. Distributions : Balanced distribution of responsibilities among entities
with strict roles.
2. Testability usually comes from the first feature
3. Ease of use and a low maintenance cost.
...
5. MVC - MVP - MVVM
Models¡ª domain data or a data access layer which manipulates the data
Views¡ª?responsible for the presentation layer (GUI), for iOS is everything
starting with ¡®UI¡¯ prefix.
Controller/Presenter/ViewModel¡ª?the glue or the mediator between the
Model and the View, responsible for altering the Model by reacting to
the user¡¯s actions performed on the View and updating the View with
changes from the Model.
8. Lighter view controllers
Separate Out Data Source and Other Protocols
Move Domain Logic into the Model
Creating the Store Class
Move Web Service Logic to the Model Layer
Design patterns
...
15. What is ReSwift ?
ReSwift is a Redux-like implementation of the unidirectional data flow
architecture in Swift.
Github : https://github.com/ReSwift/ReSwift
Documentation : http://reswift.github.io/ReSwift/master/
16. Redux - 3 principles
1. Single source of truth.
2. State is read-only.
3. Changes are made with pure functions.
17. State
The application state is defined in a single data structure which should be a
struct. This struct can have other structs as members, that allows you to add
different sub-states as your app grows.
The state struct should store your entire application state, that includes the
UI state, the navigation state and the state of your model layer.
struct AppState: StateType {
var counter: Int = 0
var navigationState = NavigationState()
}
18. Actions
Actions are used to express intended state changes. Actions don¡¯t contain
functions, instead they provide information about the intended state change,
e.g. which user should be deleted.
struct LikePostAction: Action {
let post: Post
let userLikingPost: User
}
19. Reducers
Reducers are the only place in which you should modify application state!
Reducers take the current application state and an action and return the new
transformed application state.
struct AppReducer: Reducer {
func handleAction(action: Action, state: State?) -> State {
return State(
navigationState: NavigationReducer.handleAction(action, state: state?.navigationState),
authenticationState: authenticationReducer(state?.authenticationState, action: action),
repositories: repositoriesReducer(state?.repositories, action: action),
bookmarks: bookmarksReducer(state?.bookmarks, action: action))
}
}
20. Reducers
func authenticationReducer(state: AuthenticationState?, action: Action) -> AuthenticationState {
var state = state ?? initialAuthenticationState()
switch action {
case _ as SwiftFlowInit:
break
case let action as SetOAuthURL:
state.oAuthURL = action.oAuthUrl
case let action as UpdateLoggedInState:
state.loggedInState = action.loggedInState
default:
break
}
return state
}
21. Store Subscriber
Receiving state updates from a store
Whenever the store updates its state it will notify all subscribers by calling
the newState method on themprotocol StoreSubscriber {
func newState(state: StoreSubscriberStateType)
}
store.subscribe(self) { state in
state.repositories
}
22. Action Creator
ActionCreators to perform a conditional dispatch.
An ActionCreator takes the current application state, and a reference to a
store and might or might not return an Action.
typealias ActionCreator = (state: State, store: StoreType) -> Action?
23. Middleware
Middleware allows developers to provide extensions that wrap the dispatch
function.
let loggingMiddleware: Middleware = { dispatch, getState in
return { next in
return { action in
// perform middleware logic
print(action)
// call next middleware
return next(action)
}
}
}
Store(reducer: reducer, appState: TestStringAppState(), middleware: [loggingMiddleware,
secondMiddleware])
24. Why Redux ?
Better state management
Visible
Designed
Explicit
Type system enforced
Testable transitions
#18: state, noun
the particular condition that someone or something is in at a specific time.
Although state changes over time,
the state at any particular point in time is fixed.
#19: What information do we need to provide to it?
And what actions does it produce?
#21: each component and store item is mockable, replacable, and testable in isolation.
Both outside of the store, AND outside of view controllers.