Created
February 24, 2020 20:27
-
-
Save illescasDaniel/1931a9114c800ed13ad3d7ccda68d7f4 to your computer and use it in GitHub Desktop.
GKStateMachine test example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| import GameplayKit | |
| protocol TestStatesDelegate: class { | |
| func onFetch() | |
| func onSuccess() | |
| func onError() | |
| } | |
| enum DataFetchState { | |
| class Idle: GKState { | |
| weak var delegate: TestStatesDelegate? | |
| init(delegate: TestStatesDelegate) { | |
| self.delegate = delegate | |
| } | |
| override func isValidNextState(_ stateClass: AnyClass) -> Bool { | |
| return stateClass is Fetching.Type | |
| } | |
| override func didEnter(from previousState: GKState?) { | |
| print("doing nothing") | |
| } | |
| } | |
| class Fetching: GKState { | |
| weak var delegate: TestStatesDelegate? | |
| init(delegate: TestStatesDelegate) { | |
| self.delegate = delegate | |
| } | |
| override func isValidNextState(_ stateClass: AnyClass) -> Bool { | |
| return stateClass is Failure.Type || stateClass is Success.Type | |
| } | |
| override func didEnter(from previousState: GKState?) { | |
| delegate?.onFetch() | |
| } | |
| } | |
| class Failure: GKState { | |
| weak var delegate: TestStatesDelegate? | |
| var error: Error? { | |
| didSet { | |
| self.stateMachine?.enter(DataFetchState.Failure.self) | |
| } | |
| } | |
| init(delegate: TestStatesDelegate) { | |
| self.delegate = delegate | |
| } | |
| override func isValidNextState(_ stateClass: AnyClass) -> Bool { | |
| return stateClass is Idle.Type || stateClass is Reload.Type | |
| } | |
| override func didEnter(from previousState: GKState?) { | |
| delegate?.onError() | |
| stateMachine?.enter(DataFetchState.Reload.self) | |
| } | |
| } | |
| class Success: GKState { | |
| weak var delegate: TestStatesDelegate? | |
| var data: [Person] = [] { | |
| didSet { | |
| self.stateMachine?.enter(DataFetchState.Success.self) | |
| } | |
| } | |
| init(delegate: TestStatesDelegate) { | |
| self.delegate = delegate | |
| } | |
| override func isValidNextState(_ stateClass: AnyClass) -> Bool { | |
| return stateClass is Idle.Type || stateClass is Reload.Type | |
| } | |
| override func didEnter(from previousState: GKState?) { | |
| delegate?.onSuccess() | |
| } | |
| } | |
| class Reload: GKState { | |
| weak var delegate: TestStatesDelegate? | |
| private var retryTimes = 0 | |
| private var maxRetryTimes = 5 | |
| init(delegate: TestStatesDelegate) { | |
| self.delegate = delegate | |
| } | |
| override func isValidNextState(_ stateClass: AnyClass) -> Bool { | |
| return stateClass is Fetching.Type || stateClass is Idle.Type | |
| } | |
| override func didEnter(from previousState: GKState?) { | |
| print("will reload") | |
| retryTimes += 1 | |
| guard retryTimes < self.maxRetryTimes else { | |
| print("x - Maximum retry times") | |
| stateMachine?.enter(DataFetchState.Idle.self) | |
| return | |
| } | |
| stateMachine?.enter(DataFetchState.Fetching.self) | |
| } | |
| } | |
| } | |
| // | |
| struct Person { | |
| var name: String | |
| } | |
| class TestVC { | |
| private lazy var idle = DataFetchState.Idle(delegate: self) | |
| private lazy var fetching = DataFetchState.Fetching(delegate: self) | |
| private lazy var failure = DataFetchState.Failure(delegate: self) | |
| private lazy var success = DataFetchState.Success(delegate: self) | |
| private lazy var reload = DataFetchState.Reload(delegate: self) | |
| private(set) lazy var stateMachine = GKStateMachine(states: [idle, fetching, failure, success, reload]) | |
| init() { | |
| self.stateMachine.enter(DataFetchState.Fetching.self) | |
| } | |
| } | |
| extension TestVC: TestStatesDelegate { | |
| enum Errors: Error { | |
| case something | |
| } | |
| func onFetch() { | |
| print("fetching stuff") | |
| DispatchQueue.main.asyncAfter(deadline: .now() + 1) { | |
| print("-----") | |
| if Bool.random() { // I got the data | |
| self.success.data = [Person(name: "Daniel"), Person(name: "Pepe")] | |
| } else { | |
| self.failure.error = Errors.something | |
| } | |
| } | |
| } | |
| func onError() { | |
| print("failed fetching") | |
| print(self.failure.error ?? "") | |
| } | |
| func onSuccess() { | |
| print("success fetching") | |
| print(self.success.data) | |
| } | |
| } | |
| let vc = TestVC() | |
| // | |
| RunLoop.main.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment