Update documentation
This commit is contained in:
parent
72bf7540ee
commit
2707eeb7e2
|
@ -1,23 +1,20 @@
|
||||||
# Getting started
|
# Getting started
|
||||||
To build a ui feature using the SwiftMVI you define some types and values that model your domain:
|
To build a ui feature using the SwiftMVI you define some types and values that model your domain:
|
||||||
|
|
||||||
- **ReducibleState**: A type that describes the state of your UI.
|
- **ImmutableState**: An integer as the state of your UI.
|
||||||
- **Intent**: A type that represents all of the user actions that can happen in your feature.
|
- **Intent**: A type that represents all of the user actions that can happen in your feature.
|
||||||
- **IntentReducer**: A function that handles intents and processes them over time.
|
- **IntentReducer**: A function that handles intents and processes them over time.
|
||||||
- **Processing**: Enable processing functionalities in a feature.
|
- **Processing**: Enable processing functionalities in a feature.
|
||||||
|
|
||||||
As a basic example, consider a UI that shows a number along with "+" and "−" buttons that increment and decrement the number.
|
As a basic example, consider a UI that shows a number along with **+** and **−** buttons that increment and decrement the number.
|
||||||
|
|
||||||
Here we need to define a type for the feature's state, which consists of an integer for the current count:
|
Here we need to define a type for the feature's state, which consists of an integer for the current count:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
import SwiftMVI
|
import SwiftMVI
|
||||||
|
|
||||||
class Feature: ObservableObject, ReducibleState {
|
class Feature: ObservableObject, ImmutableState {
|
||||||
class State {
|
var state = 0
|
||||||
var count = 0
|
|
||||||
}
|
|
||||||
var state = State()
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -41,11 +38,11 @@ extension Feature: IntentReducer, Processing {
|
||||||
switch intent {
|
switch intent {
|
||||||
case .increment:
|
case .increment:
|
||||||
state {
|
state {
|
||||||
$0.count += 1
|
$0 += 1
|
||||||
}
|
}
|
||||||
case .decrement:
|
case .decrement:
|
||||||
state {
|
state {
|
||||||
$0.count -= 1
|
$0 -= 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +61,7 @@ struct FeatureView: View {
|
||||||
VStack {
|
VStack {
|
||||||
HStack {
|
HStack {
|
||||||
Button("−") { feature(.decrement) }
|
Button("−") { feature(.decrement) }
|
||||||
Text("\(feature.state.count)")
|
Text("\(feature.state)")
|
||||||
Button("+") { feature(.increment) }
|
Button("+") { feature(.increment) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
# Getting started
|
||||||
|
To build a ui feature using the SwiftMVI you define some types and values that model your domain:
|
||||||
|
|
||||||
|
- **MutableState**: A type that describes the state of your UI.
|
||||||
|
- **Intent**: A type that represents all of the user actions that can happen in your feature.
|
||||||
|
- **IntentReducer**: A function that handles intents and processes them over time.
|
||||||
|
- **Processing**: Enable processing functionalities in a feature.
|
||||||
|
|
||||||
|
As a basic example, consider a UI that shows a number along with "+" and "−" buttons that increment and decrement the number.
|
||||||
|
|
||||||
|
Here we need to define a type for the feature's state, which consists of an integer for the current count:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
import SwiftMVI
|
||||||
|
|
||||||
|
class Feature: ObservableObject, MutableState {
|
||||||
|
class State {
|
||||||
|
var count = 0
|
||||||
|
}
|
||||||
|
var state = State()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
We also need to define a type for the feature's intents, there are two intents one for the increase and one for decrease:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
extension Feature: IntentReducer {
|
||||||
|
enum Intent {
|
||||||
|
case increment
|
||||||
|
case decrement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And then we implement the reduce method which is responsible for handling the behaviour of the feature. In this example to change the state we need to add ``Processing`` protocol and call ``.state``:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
extension Feature: IntentReducer, Processing {
|
||||||
|
enum Intent { ... }
|
||||||
|
func reduce(intent: Intent) {
|
||||||
|
switch intent {
|
||||||
|
case .increment:
|
||||||
|
state {
|
||||||
|
$0.count += 1
|
||||||
|
}
|
||||||
|
case .decrement:
|
||||||
|
state {
|
||||||
|
$0.count -= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
And then finally we define the view that displays the feature, adding as ``StateObject`` or ``ObservedObject`` and call by passing its ``Intent``:
|
||||||
|
|
||||||
|
|
||||||
|
```swift
|
||||||
|
struct FeatureView: View {
|
||||||
|
@StateObject var feature = Feature()
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
HStack {
|
||||||
|
Button("−") { feature(.decrement) }
|
||||||
|
Text("\(feature.state.count)")
|
||||||
|
Button("+") { feature(.increment) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
|
@ -26,7 +26,7 @@ You can use Swift Package Manager to integrate the library by adding the followi
|
||||||
## Usage
|
## Usage
|
||||||
To build a ui feature using the SwiftMVI you define some types and values that model your domain:
|
To build a ui feature using the SwiftMVI you define some types and values that model your domain:
|
||||||
|
|
||||||
- **ReducibleState**: A type that describes the state of your UI.
|
- **MutableState**: A type that describes the state of your UI.
|
||||||
- **Intent**: A type that represents all of the actions that can happen in your feature, such as user actions, notifications, event sources and more.
|
- **Intent**: A type that represents all of the actions that can happen in your feature, such as user actions, notifications, event sources and more.
|
||||||
- **IntentReducer**: A function that handle intents and process them over time.
|
- **IntentReducer**: A function that handle intents and process them over time.
|
||||||
- **Processing**: Enable processing functionalities in a feature.
|
- **Processing**: Enable processing functionalities in a feature.
|
||||||
|
@ -38,7 +38,7 @@ In here we need to define a type for the feature's state, which consists of an i
|
||||||
```swift
|
```swift
|
||||||
import SwiftMVI
|
import SwiftMVI
|
||||||
|
|
||||||
class Feature: ObservableObject, ReducibleState {
|
class Feature: ObservableObject, MutableState {
|
||||||
class State {
|
class State {
|
||||||
var count = 0
|
var count = 0
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ struct FeatureView: View {
|
||||||
- ``AsyncReactionReducer``
|
- ``AsyncReactionReducer``
|
||||||
|
|
||||||
### State
|
### State
|
||||||
- ``ReducibleState``
|
- ``MutableState``
|
||||||
|
|
||||||
### Processing
|
### Processing
|
||||||
- ``ReducerComponent``
|
- ``ReducerComponent``
|
||||||
|
|
19
README.md
19
README.md
|
@ -19,6 +19,25 @@ There are some important differences compared to other MVI implementations.
|
||||||
First of all, in SwiftMVI state is a mutable ``ObservableObject``, therefore the reducers are not return anything not even an effect. The reducers can connect using the ``Processing`` protocol and its api. Your existing Combine publishers can be connected using ```.bind``` method and your implemented ``Feature`` can be inserted as A **Publisher** instance. in any process using ``EventReducer``.
|
First of all, in SwiftMVI state is a mutable ``ObservableObject``, therefore the reducers are not return anything not even an effect. The reducers can connect using the ``Processing`` protocol and its api. Your existing Combine publishers can be connected using ```.bind``` method and your implemented ``Feature`` can be inserted as A **Publisher** instance. in any process using ``EventReducer``.
|
||||||
|
|
||||||
|
|
||||||
|
### Reducibles
|
||||||
|
- **ImmutableState** Use this type when your State is immutable (struct, enum, etc...)
|
||||||
|
- **MutableState** Use this type when your State is mutable (class)
|
||||||
|
|
||||||
|
### Reducers
|
||||||
|
- **IntentReducer** An ability to process incomming intents from user.
|
||||||
|
- **AsyncIntentReducer** An async version of **IntentReducer**.
|
||||||
|
- **ActionReducer** An ability to process incomming action from itself or other reducers.
|
||||||
|
- **AsyncActionReducer** An async version of **ActionReducer**.
|
||||||
|
- **ReactionReducer** An ActionReducer that returns a Reaction.
|
||||||
|
- **AsyncReactionReducer** An async version of **ReactionReducer**.
|
||||||
|
- **EffectReducer** An ability to proccess incomming events from **Processing**.
|
||||||
|
- **AsyncEffectReducer** An async version of **EffectReducer**.
|
||||||
|
|
||||||
|
### Binding combine publisher or another feature to an:
|
||||||
|
- Intent ```bind(publisher){ .myIntent($0.value) }
|
||||||
|
- Action ```bind(publisher){ .myAction($0.value) }
|
||||||
|
- Effect ```bind(publisher){ .myEffect($0.value) }
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
You can use Swift Package Manager to integrate the library by adding the following dependency in your Package.swift file or by adding directly within Xcode:
|
You can use Swift Package Manager to integrate the library by adding the following dependency in your Package.swift file or by adding directly within Xcode:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue