Skip to content
This repository has been archived by the owner on Sep 18, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Simplify async actions
  • Loading branch information
gokselkoksal committed Jul 20, 2017
1 parent b397141 commit eba0cf9
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 84 deletions.
5 changes: 5 additions & 0 deletions Core/Sources/Component.swift
Expand Up @@ -58,4 +58,9 @@ open class Component<StateType: State>: AnyComponent {
navigationDelegate?.component(self, willFireNavigation: navigation)
subscriptionManager.publish(navigation)
}

public final func commit(_ newState: State, _ navigation: Navigation) {
commit(newState)
commit(navigation)
}
}
80 changes: 33 additions & 47 deletions iOS Example/LoginComponent.swift
Expand Up @@ -10,9 +10,8 @@ import Foundation
import Core

enum LoginAction: Action {
case setLoading(Bool)
case tick
case setResult(Result<Void>)
case verifyOTP(String)
}

struct LoginState: State {
Expand All @@ -30,64 +29,51 @@ class LoginComponent: Component<LoginState> {
super.init(state: LoginState())
}

func commandToVerifyOTP(withCode code: String) -> VerifyOTPCommand {
return VerifyOTPCommand(service: service, code: code)
}

override func process(_ action: Action) {
guard let action = action as? LoginAction else { return }
var state = self.state
state.result = nil
switch action {
case .setLoading(let isLoading):
state.isLoading = isLoading
case .tick:
switch state.timerStatus {
case .idle:
state.timerStatus = .active(seconds: 60)
default:
do {
try state.timerStatus.tick()
} catch {
state.result = .failure(error)
commit(state)
commit(BasicNavigation.pop([self]))
return
}
tick()
case .verifyOTP(let code):
verifyOTP(code)
}
}

private func tick() {
var state = self.state
switch state.timerStatus {
case .idle:
state.timerStatus = .active(seconds: 60)
default:
do {
try state.timerStatus.tick()
} catch {
state.result = .failure(error)
commit(state, BasicNavigation.pop([self]))
return
}
case .setResult(let result):
}
commit(state)
}

private func verifyOTP(_ code: String) {
var state = self.state
state.isLoading = true
commit(state)
service.verifyOTP { [weak self] (result) in
guard let strongSelf = self else { return }
state.isLoading = false
state.timerStatus = .finished
state.result = result
switch result {
case .success():
commit(state)
commit(BasicNavigation.push(HomeComponent(), from: self))
return
let navigation = BasicNavigation.push(HomeComponent(), from: strongSelf)
strongSelf.commit(state, navigation)
case .failure(let error):
print(error)
commit(state)
strongSelf.commit(state)
}
}
commit(state)
}
}

class VerifyOTPCommand: Command {

let service: OTPService
let code: String

init(service: OTPService, code: String) {
self.service = service
self.code = code
}

func execute(on component: Component<LoginState>, core: Core) {
core.dispatch(LoginAction.setLoading(true))
service.verifyOTP { (result) in
core.dispatch(LoginAction.setLoading(false))
core.dispatch(LoginAction.setResult(result))
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion iOS Example/LoginViewController.swift
Expand Up @@ -47,7 +47,7 @@ class LoginViewController: UIViewController {

@IBAction func submitTapped(_ sender: UIButton) {
guard let code = otpTextField.text else { return }
core.dispatch(component.commandToVerifyOTP(withCode: code))
core.dispatch(LoginAction.verifyOTP(code))
}
}

Expand Down
52 changes: 17 additions & 35 deletions iOS Example/OTPComponent.swift
Expand Up @@ -10,8 +10,7 @@ import Foundation
import Core

enum OTPAction: Action {
case setLoading(Bool)
case setResult(Result<Void>)
case requestOTP(phoneNumber: String)
}

struct OTPState: State {
Expand All @@ -28,47 +27,30 @@ class OTPComponent: Component<OTPState> {
super.init(state: OTPState())
}

func commandToRequestOTP(withPhoneNumber phoneNumber: String) -> RequestOTPCommand {
return RequestOTPCommand(service: service, phoneNumber: phoneNumber)
}

override func process(_ action: Action) {
guard let action = action as? OTPAction else { return }
var state = self.state
switch action {
case .setLoading(let isLoading):
state.isLoading = isLoading
case .setResult(let result):
case .requestOTP(phoneNumber: let phoneNumber):
requestOTP(toPhoneNumber: phoneNumber)
}
}

private func requestOTP(toPhoneNumber phoneNumber: String) {
var state = self.state
state.isLoading = true
commit(state)
service.requestOTP { [weak self] (result) in
guard let strongSelf = self else { return }
state.isLoading = false
state.result = result
switch result {
case .success():
let component = LoginComponent(service: service)
commit(state)
commit(BasicNavigation.push(component, from: self))
return
let component = LoginComponent(service: strongSelf.service)
let navigation = BasicNavigation.push(component, from: strongSelf)
strongSelf.commit(state, navigation)
default:
break
strongSelf.commit(state)
}
}
commit(state)
}
}

class RequestOTPCommand: Command {

let service: OTPService
let phoneNumber: String

init(service: OTPService, phoneNumber: String) {
self.service = service
self.phoneNumber = phoneNumber
}

func execute(on component: Component<OTPState>, core: Core) {
core.dispatch(OTPAction.setLoading(true))
service.requestOTP { (result) in
core.dispatch(OTPAction.setLoading(false))
core.dispatch(OTPAction.setResult(result))
}
}
}
2 changes: 1 addition & 1 deletion iOS Example/OTPViewController.swift
Expand Up @@ -37,7 +37,7 @@ class OTPViewController: UIViewController {

@IBAction func sendOTPTapped(_ sender: UIButton) {
guard let phoneNumber = phoneNumberField.text else { return }
core.dispatch(component.commandToRequestOTP(withPhoneNumber: phoneNumber))
core.dispatch(OTPAction.requestOTP(phoneNumber: phoneNumber))
}
}

Expand Down

0 comments on commit eba0cf9

Please sign in to comment.