- Notifications
You must be signed in to change notification settings - Fork7
This is what makes the Flux design pattern possible.
License
marty-suzuki/FluxCapacitor
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
FluxCapacitor makes implementingFlux design pattern easily with protocols and typealias.
- Storable protocol
- Actionable protocol
- DispatchState protocol
- Xcode 10.1 or later
- Swift 4.2 or later
- iOS 10.0 or later
FluxCapacitor is available throughCocoaPods. To installit, simply add the following line to your Podfile:
pod"FluxCapacitor"
If you’re usingCarthage, simply add FluxCapacitor to yourCartfile:
github"marty-suzuki/FluxCapacitor"
This is ViewController sample that uses Flux design pattern. If ViewController calls fetchRepositories method of RepositoryAction, it is reloaded automatically by observed changes of Constant in RepositoryStore after fetched repositories from Github. Introducing how to implement Flux design pattern withFluxCapacitor.
finalclassUserRepositoryViewController:UIViewController{@IBOutlet weakvartableView:UITableView!privateletrepositoryAction=RepositoryAction()privateletrepositoryStore=RepositoryStore.instantiate()privateletuserStore=UserStore.instantiate()privateletdustBuster=DustBuster()privateletdataSource=UserRepositoryViewDataSource()overridefunc viewDidLoad(){ super.viewDidLoad() dataSource.configure(with: tableView)observeStore()iflet user= userStore.selectedUser.value{ repositoryAction.fetchRepositories(withUserId: user.id, after:nil)}}privatefunc observeStore(){ repositoryStore.repositories.observe(on:.main, changes:{[weak self] _inself?.tableView.reloadData()}).cleaned(by: dustBuster)}}
First of all, implementingDispatchState. It connects Action and Store, but it plays a role that don't depend directly each other.
extensionDispatcher{enumRepository:DispatchState{typealiasRelatedStoreType=RepositoryStoretypealiasRelatedActionType=RepositoryActioncase isRepositoryFetching(Bool)case addRepositories([GithubApiSession.Repository])case removeAllRepositories}}
ImplementingStore withStorable protocol.func reduce(with:_) is called when Dispatcher dispatches DispatchStateType. Please update store's value with Associated Values.
finalclassRepositoryStore:Storable{typealiasDispatchStateType=Dispatcher.RepositoryletisRepositoryFetching:Constant<Bool>privatelet_isRepositoryFetching=Variable<Bool>(false)letrepositories:Constant<[Repository]>privatelet_repositories=Variable<[Repository]>([])requiredinit(){self.isRepositoryFetching=Constant(_isRepositoryFetching)self.repositories=Constant(_repositories)}func reduce(with state:Dispatcher.Repository){switch state{case.isRepositoryFetching(let value): _isRepositoryFetching.value= valuecase.addRepositories(let value): _repositories.value.append(contentsOf: value)case.removeAllRepositories: _repositories.value.removeAll()}}}
If you want to use any store, please useXXXStore.instantiate(). That static method returns its reference or new instance.If you want to unregister any store from Dispatcher, please callxxxStore.clear().
ImplementingAction withActionable protocol. If you call invoke method, it can dispatch value related DispatchStateType.
finalclassRepositoryAction:Actionable{typealiasDispatchStateType=Dispatcher.Repositoryprivateletsession:ApiSessioninit(session:ApiSession=.shared){self.session= session}func fetchRepositories(withUserId id:String, after:String?){invoke(.isRepositoryFetching(true))letrequest=UserNodeRequest(id: id, after: after) _= session.send(request){[weak self]inswitch $0{case.success(let value):self?.invoke(.addRepositories(value.nodes))case.failure:break}self?.invoke(.isRepositoryFetching(false))}}}
You can initialize a store withinstantiate(). If reference of store is left, that method returns remained one. If reference is not left, that method returns new instance.You can observe changes by Constant or Variable. When called observe, it returnsDust. So, clean up withDustBuster.
letdustBuster=DustBuster()func observeStore(){ // Get store instanceletstore=RepositoryStore.instantiate() // Observer changes of repositories that is `Constant<[Github.Repository]>`. store.repositories.observe(on:.main){ valuein // do something}.cleaned(by: dustBuster)}
Robert Zemeckis (1989) Back to the future Part II, Universal Pictures
Variable<Element> has getter and setter of Element.
letintVal=Variable<Int>(0)intVal.value=1print(intVal.value) // 1
Constant<Element> has only getter of Element. So, you can initialize Constant with Variable.Variable shares its value with Constant.
letvariable=Variable<Int>(0)letconstant=Constant(variable)variable.value=1print(variable.value) // 1print(constant.value) // 1
In addition, Constant that initialize with some Variable, it can use same observation.
letvariable=Variable<Int>(0)letconstant=Constant(variable)_= variable.observe{ valueinprint(value) // 0 -> 10}_= constant.observe{ valueinprint(value) // 0 -> 10}variable.value=10
You can use FluxCapacitor with RxSwift likethis link.
Or implementfunc asObservable() like this.
// ConstantextensionPrimitiveValuewhere Trait==ImmutableTrait{func asObservable()->Observable<Element>{returnObservable.create{[weak self] observerinletdust=self?.observe{ observer.onNext($0)}returnDisposables.create{ dust?.clean()}}}}
To run the example project, clone the repo, and runpod install andcarthage update from the Example directory first. In addition, you must set Github Personal access token.
// ApiSessionType.swiftextensionApiSession:ApiSessionType{staticletshared:ApiSession={lettoken="" // Your Personal Access TokenreturnApiSession(injectToken:{InjectableToken(token: token)})}()}
Application structure is like below.
- SearchViewController (with RxSwift) You can search Github user.
- FavoriteViewController You can stock favorites on memory.
- UserRepositoryViewController You can display a user's repositories.
- RepositoryViewController You can display webpage of repository, and add favorites on memory.
GithubKitForSample is used in this sample project.
Flux + MVVM Sample ishere.
FluxCapacitor 0.10.0 Migration Guide
marty-suzuki,s1180183@gmail.com
FluxCapacitor is available under the MIT license. See the LICENSE file for more info.
About
This is what makes the Flux design pattern possible.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.


