This repository was archived by the owner on Dec 12, 2021. It is now read-only.
- Notifications
You must be signed in to change notification settings - Fork6
🤖 ReactiveCocoa + State Machine, inspired by Redux and Elm.
License
NotificationsYou must be signed in to change notification settings
inamiy/ReactiveAutomaton
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
NOTE: This repository has been discontinued in favor ofActomaton.
ReactiveCocoa + State Machine, inspired byRedux andElm. A successor ofSwiftState.
(Demo app is available atReactiveCocoaCatalog)
To make a state transition diagram like abovewith additional effects, follow these steps:
// 1. Define `State`s and `Input`s.enumState{case loggedOut, loggingIn, loggedIn, loggingOut}enumInput{case login, loginOK, logout, logoutOKcase forceLogout}// Additional effects (`SignalProducer`s) while state-transitioning.// (NOTE: Use `SignalProducer.empty` for no effect)letloginOKProducer= /* show UI, setup DB, request APIs, ..., and send `Input.loginOK` */let logoutOKProducer= /* show UI, clear cache, cancel APIs, ..., and send `Input.logoutOK` */let forceLogoutOKProducer= /* do something more special, ..., and send `Input.logoutOK` */let canForceLogout:(State)-> Bool=[.loggingIn,.loggedIn].contains// 2. Setup state-transition mappings.letmappings:[Automaton<State,Input>.EffectMapping]=[ /* Input | fromState => toState | Effect */ /* ----------------------------------------------------------*/.login |.loggedOut=>.loggingIn | loginOKProducer,.loginOK |.loggingIn=>.loggedIn |.empty,.logout |.loggedIn=>.loggingOut | logoutOKProducer,.logoutOK |.loggingOut=>.loggedOut |.empty,.forceLogout | canForceLogout=>.loggingOut | forceLogoutOKProducer]// 3. Prepare input pipe for sending `Input` to `Automaton`.let(inputSignal, inputObserver)=Signal<Input,NoError>.pipe()// 4. Setup `Automaton`.letautomaton=Automaton( state:.loggedOut, input: inputSignal, mapping:reduce(mappings), // combine mappings using `reduce` helper strategy:.latest // NOTE: `.latest` cancels previous running effect)// Observe state-transition replies (`.success` or `.failure`).automaton.replies.observeNext{ replyinprint("received reply =\(reply)")}// Observe current state changes.automaton.state.producer.startWithValues{ stateinprint("current state =\(state)")}
And let's test!
letsend= inputObserver.send(value:)expect(automaton.state.value)==.loggedIn // already logged insend(Input.logout)expect(automaton.state.value)==.loggingOut // logging out...// `logoutOKProducer` will automatically send `Input.logoutOK` later// and transit to `State.loggedOut`.expect(automaton.state.value)==.loggedOut // already logged outsend(Input.login)expect(automaton.state.value)==.loggingIn // logging in...// `loginOKProducer` will automatically send `Input.loginOK` later// and transit to `State.loggedIn`.// 👨🏽 < But wait, there's more!// Let's send `Input.forceLogout` immediately after `State.loggingIn`.send(Input.forceLogout) // 💥💣💥expect(automaton.state.value)==.loggingOut // logging out...// `forceLogoutOKProducer` will automatically send `Input.logoutOK` later// and transit to `State.loggedOut`.
Note thatany sizes ofState andInput will work usingReactiveAutomaton, from single state (like above example) to covering whole app's states (like React.js + Redux architecture).
- iOSDC 2016 (Tokyo, in Japanese) (2016/08/20)
- iOSConf SG (Singapore, in English) (2016/10/20-21)
About
🤖 ReactiveCocoa + State Machine, inspired by Redux and Elm.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
No packages published
Uh oh!
There was an error while loading.Please reload this page.
