Core helps you design applications in a way that the app flow is driven by business layer, instead of UI layer. It also promotes unidirectional data flow between components for consistency, high testability and powerful debugging.
Related Article: Architecting iOS Apps with "Core"
- Core is simply a box that represents our app.
- Components are our features.
- Actions are the changes that happen on the system.
- Subscribers can be anything. It can be a console app. It can be an iOS app. It can be our test suite.
Core can be seen as a Redux, Flux and MVVM hybrid.
-
Redux is static. It expects you to define a big fat structure that expresses the app state in compile time. This can be challenging if you have reusable controllers that you present here and there a number of times. Especially in cases where your application flow is altered by server responses, you cannot easily define your app state in compile time without hacking the architecture. Core is dynamic. You only need to define the state and actions for the component you are working on. Transition between components is handled dynamically.
-
In Redux, there is no standard way to implement navigation between components. With Core, you get native navigation support.
-
Redux focuses on application state, whereas Core focuses on isolated component state. In this regard, I find it easier to work in isolation on one component rather than getting lost in huge application state.
-
In Redux, since the state is global, itβs easy to forget to do state clean-up when a screen is popped from the navigation stack. In Core, since every component stores its own state, when you remove a component from the tree, state gets disposed along with it. This is handled internally by navigation mechanism.
I'll follow the tradition and start with countdown example.
State:
struct CountdownState: State {
var count: UInt
}
Actions:
enum CountdownAction: Action {
case tick
}
Component:
class CountdownComponent: Component<CountdownState> {
func process(action: Action) {
guard let action = action as? LoginAction else { return }
switch action {
case .tick:
tick()
}
}
private func tick() {
var state = state
state.count = state.count - 1
if state.count == 0 {
let nextComponent = ResultComponent()
let navigation = BasicNavigation.push(nextComponent, from: self)
commit(state, navigation)
} else {
commit(state)
}
}
}
More complex examples:
- Level 2 Sample: iOS Example
- Level 3 Sample: Movies
Using CocoaPods
Add the following line to your Podfile
:
pod 'CoreArchitecture'
Using Carthage
Add the following line to your Cartfile
:
github "gokselkoksal/Core"
Drag and drop Sources
folder to your project.
It's highly recommended to use a dependency manager like CocoaPods or Carthage.
You can also check out ReSwift, Reactor or Dispatch for pure Redux and Flux implementations for Swift.
Core is available under the MIT license.