Last active
March 4, 2020 18:31
-
-
Save velyan/c1e20503ae82954d77fd451bc18f6490 to your computer and use it in GitHub Desktop.
Swift State Pattern
This file contains 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 UIKit | |
protocol Stateful { | |
func loggedIn() | |
func loggedOut() | |
} | |
extension UIViewController: Stateful { | |
func loggedIn() { | |
navigationItem.loggedIn() | |
} | |
func loggedOut() { | |
navigationItem.loggedOut() | |
} | |
} | |
extension UINavigationItem: Stateful { | |
func loggedIn() { | |
rightBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: nil, action: nil) | |
} | |
func loggedOut() { | |
rightBarButtonItem = UIBarButtonItem(title: "Login", style: .plain, target: nil, action: nil) | |
} | |
} |
This file contains 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 | |
fileprivate protocol Statelike { | |
var stateMachine: StateMachine { get } | |
func logIn() | |
func logOut() | |
} | |
extension Statelike { | |
func logIn() {} | |
func logOut() {} | |
} | |
fileprivate struct LoggedIn: Statelike { | |
var stateMachine: StateMachine | |
func logOut() { | |
stateMachine.setState(LoggedOut(stateMachine: stateMachine)) | |
stateMachine.loggedOut?() | |
} | |
} | |
fileprivate struct LoggedOut: Statelike { | |
var stateMachine: StateMachine | |
func logIn() { | |
stateMachine.setState(LoggedIn(stateMachine: stateMachine)) | |
stateMachine.loggedIn?() | |
} | |
} | |
class StateMachine { | |
typealias StateHandler = () -> () | |
var loggedIn: StateHandler? | |
var loggedOut: StateHandler? | |
private lazy var state: Statelike = { | |
return LoggedOut(stateMachine: self) | |
}() | |
@objc func logIn() { | |
state.logIn() | |
} | |
@objc func logOut() { | |
state.logOut() | |
} | |
fileprivate func setState(_ state: Statelike) { | |
self.state = state | |
} | |
} |
This file contains 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 UIKit | |
extension UIBarButtonItem { | |
func addTarget(_ target: AnyObject?, action: Selector){ | |
self.target = target | |
self.action = action | |
} | |
} | |
extension ViewController { | |
override func loggedIn() { | |
super.loggedIn() | |
self.navigationItem.rightBarButtonItem?.addTarget(self.stateMachine, action: #selector(StateMachine.logOut)) | |
} | |
override func loggedOut() { | |
super.loggedOut() | |
self.navigationItem.rightBarButtonItem?.addTarget(self.stateMachine, action: #selector(StateMachine.logIn)) | |
} | |
} | |
class ViewController: UIViewController { | |
var stateMachine = StateMachine() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
stateMachine.loggedIn = { self.loggedIn() } | |
stateMachine.loggedOut = { self.loggedOut() } | |
stateMachine.logIn() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment