Skip to content

Instantly share code, notes, and snippets.

View twittemb's full-sized avatar

Thibault Wittemberg twittemb

View GitHub Profile
public class AnyCup<LiquidType: Liquid>: Cup {
// inner mechanism to "remember" the behavior of the cup passed in the init function
private let fillClosure: (LiquidType) -> Void
private let liquidClosure: () -> LiquidType?
init<CupType: Cup>(with cup: CupType) where CupType.LiquidType == LiquidType {
self.fillClosure = cup.fill
self.liquidClosure = { return cup.liquid }
}
let loadUserAction: Observable<Action> = UserApi.fetchUser(id: 1).map { user in
return LoadUserAction(user: user)
}
store.dispatch(action: loadUserAction)
extension Observable: Action where Element == Action {
public func toAsync () -> Observable<Action> {
return self.map { $0 as Action }
}
}
public protocol Action {
func toAsync () -> Observable<Action>
}
extension Action {
public func toAsync () -> Observable<Action> {
return Observable<Action>.just(self)
}
}
// init the Store with the list of the Reducers to apply
let store = Store<AppState>(withReducers: [userReducer, contactsReducer])
...
// listen for the UserState mutations
let userState: Driver<UserState> = store.state { (appState) -> UserState in
return appState.userState
}
func state<SubState: Equatable>(from: (StateType) -> SubState) -> Driver<SubState> {
return self.stateSubject
.asDriver()
.map { (state) -> SubStateType in
return from(state)
}.distinctUntilChanged()
}
struct Lens<A,B> {
let from : A -> B
}
let firstname = Lens<Contact, String>(from: { $0.user.firstname })
...
let myContact = Contact(user: User(firstname: "James", lastname: "Kirk"),
isConnected: true)
func userReducer (state: AppState?, action: Action) -> AppState {
var currentState = state ?? AppState(userState: UserState.empty,
contactsState: ContactsState.empty)
// according to the action we create a new state
switch action {
case let action as LoadUserAction:
currentState.userState = UserState.loaded(User(firstname: action.firstname,
lastname: action.lastname))
struct LoadUserAction: Action {
let firstname: String
let lastname: String
}
struct LoadContactsAction: Action {
let contacts: [Contact]
}
public func dispatch (action: Action) {
// every received action is converted to an async action
action
.toAsync()
.map { [unowned self] (action) -> StateType? in
return self.reducers.reduce(self.state.value, { (state, reducer) -> StateType? in
return reducer(state, action)
})
}.subscribe(onNext: { [unowned self] (newState) in
self.state.accept(newState)