Skip to content

Instantly share code, notes, and snippets.

@g-mark
Last active December 1, 2019 20:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save g-mark/8bb0db6db97d9a0532a15d9a5ecbbe1d to your computer and use it in GitHub Desktop.
Save g-mark/8bb0db6db97d9a0532a15d9a5ecbbe1d to your computer and use it in GitHub Desktop.
Lasso Intro Article
enum LoginScreenModule: ScreenModule {
enum Action: Equatable {
case didUpdateUsername(String)
case didUpdatePassword(String)
case didTapLogin
}
enum Output: Equatable {
case userDidLogin
}
struct State: Equatable {
var username: String = ""
var password: String = ""
var error: String? = nil
}
static var defaultInitialState: State {
return State()
}
}
final class LoginScreenStore: LassoStore<LoginScreenModule> {
override handleAction(_ action: Action) {
switch action {
case .didUpdateUsername(let username):
update { state in
state.username = username
}
case .didUpdatePassword(let password):
update { state in
state.password = password
}
case .didTapLogin:
LoginService.login(state.username,
state.password) { [weak self] success in
self?.update { state in
state.error = success ? nil : "Invalid login"
}
if success {
self?.dispatchOutput(.userDidLogin)
}
}
}
}
}
final class LoginScreenViewController: UIViewController, LassoView {
let store: LoginScreenModule.ViewStore
init(_ store: ViewStore) {
self.store = store
// omitted for clarity: create/layout the UIKit controls
setupBindings()
}
private let usernameField: UITextField
private let passwordField: UITextField
private let errorLabel: UILabel
private let loginButton: UIButton
private func setupBindings() {
// State change inputs:
store.observeState(\.username) { [weak self] username in
self?.usernameField.text = username
}
store.observeState(\.password) { [weak self] password in
self?.passwordField.text = password
}
store.observeState(\.error) { [weak self] error in
self?.errorLabel.text = error
}
// Action outputs:
usernameField.bindTextDidChange(to: store) { text in
.didUpdateUsername(text)
}
passwordField.bindTextDidChange(to: store) { text in
.didUpdatePassword(text)
}
loginButton.bind(to: store, action: .didTapLogin)
}
}
enum LoginService {
static func login(_ username: String,
_ password: String,
completion: @escaping (Bool) -> Void) {
...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment