Skip to content

Commit

Permalink
Updated documentation for docc (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
KazaiMazai authored Sep 5, 2024
1 parent f9d7a6b commit ddb23b4
Show file tree
Hide file tree
Showing 14 changed files with 932 additions and 492 deletions.
485 changes: 0 additions & 485 deletions Docs/Migration-Guides.md

This file was deleted.

21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/KazaiMazai/Puredux/blob/main/Docs/Resources/Logo-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://github.com/KazaiMazai/Puredux/blob/main/Docs/Resources/Logo.svg">
<img src="https://github.com/KazaiMazai/Puredux/blob/main/Docs/Resources/Logo.svg">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/KazaiMazai/Puredux/blob/main/Sources/Puredux/Documentation.docc/Resources/Logo-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://github.com/KazaiMazai/Puredux/blob/main/Sources/Puredux/Documentation.docc/Resources/Logo.svg">
<img src="https://github.com/KazaiMazai/Puredux/blob/main/Sources/Puredux/Documentation.docc/Resources/Logo.svg">
</picture>


Expand Down Expand Up @@ -256,8 +256,16 @@ store.dispatch(FetchDataAction())

```

## Performance

Puredux offers a robust strategy for addressing the performance challenges commonly faced in iOS applications. It provides several key optimizations to enhance app responsiveness and efficiency, including:

- Reducers background execution: Offloads reducer logic to background threads to improve overall app performance.
- State updates deduplication: Minimizes redundant state updates, reducing unnecessary re-renders and improving processing efficiency.
- Granular UI updates: Ensures only the necessary parts of the UI are updated, enhancing responsiveness.
- UI updates debouncing: Prevents excessive UI updates by intelligently controlling the frequency of updates.
- Two-step UI updates with background task offloading: Heavy computational tasks are handled in the background, with UI updates executed in a structured two-step process to ensure smooth, lag-free interactions.

## Performance Tuning

### Quality of Service

Expand Down Expand Up @@ -455,9 +463,10 @@ https://github.com/KazaiMazai/Puredux

## Documentation

- [Documentation](https://swiftpackageindex.com/KazaiMazai/Puredux/main/documentation/puredux)
- [Documentation v1.9.x](https://swiftpackageindex.com/KazaiMazai/Puredux/1.9.2/documentation/puredux)
- [Archive](https://github.com/KazaiMazai/Puredux/blob/main/Docs/Archive)
- [Migration Guides](https://github.com/KazaiMazai/Puredux/blob/main/Docs/Migration-Guides.md)
- [Documentation Archive](https://github.com/KazaiMazai/Puredux/blob/main/Sources/Puredux/Documentation.docc/Archive)
- [Migration Guides](https://github.com/KazaiMazai/Puredux/blob/main/Sources/Puredux/Documentation.docc/MigrationGuides.md)

## Licensing

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

# Documentation v1.x

## Basics

- State is a type describing the whole application state or a part of it
Expand Down
121 changes: 121 additions & 0 deletions Sources/Puredux/Documentation.docc/GettingStarted.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Getting Started

## Installation

### Swift Package Manager

Puredux is available through Swift Package Manager.

To install it, in Xcode 11.0 or later select File > Swift Packages > Add Package Dependency... and add Puredux repositoies URLs for the modules requried:

```
https://github.com/KazaiMazai/Puredux
```

## Basics

- State is a type describing the whole application state or a part of it
- Actions describe events that may happen in the system and mutate the state
- Reducer is a function, that describes how Actions mutate the state
- Store is the heart of the whole thing. It takes Initial State and Reducer, performs mutations when Actions dispatched and deilvers new State to Observers

## Store Definitions

```swift
// Let's cover actions with a protocol

protocol Action {

}

// Define root AppState

struct AppState {
// ...

mutating func reduce(_ action: Action) {
// ...
}
}

// Injected root store

extension Injected {
@InjectEntry var root = StateStore<AppState, Action>(AppState()) { state, action in
state.reduce(action)
}
}
```

## UI Bindings


### SwiftUI

```swift

// View might need a local state that we don't need to share with the whole app

struct ViewState {
// ...

mutating func reduce(_ action: Action) {
// ...
}
}

struct ContentView: View {
// We can take an injected root store,
// create a local state store and merge them together.
@State var store: StoreOf(\.root).with(ViewState()) { state, action in
state.reduce(action)
}

@State var viewState: (AppState, ViewState)?

var body: some View {
MyView(viewState)
.subscribe(store) { viewState = $0 }
.onAppear {
dispatch(SomeAction())
}
}
}

```

### UIKit

```swift

// We can do the same thing almost with the same API for UIKit view controller:

struct MyScreenState {
// ...

mutating func reduce(_ action: Action) {
// ...
}
}

class MyViewController: ViewController {
var store: StoreOf(\.root).with(MyScreenState()) { state, action in
state.reduce(action)
}

override func viewDidLoad() {
super.viewDidLoad()

subscribe(store) { [weak self] in
// Handle updates with the derived props
self?.updateUI(with: $0)
}
}

private func updateUI(with state: (AppState, MyScreenState)) {
// Update UI elements with the new view state
}
}

```

Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@

# Migrating to 1.1.x

## Store migration

## 1. Migrate From `RootStore` to `StoreFactory`:

Before:

```swift
let rootStore = RootStore<AppState, Action>(
queue: StoreQueue = .global(qos: .userInteractive)
initialState: initialState,
reducer: reducer
)

let store: Store<AppState, Action> = rootStore.store()

```

Now:

```swift
let storeFactory = StoreFactory<AppState, Action>(
initialState: initialState,
qos: .userInteractive,
reducer: reducer
)

let store: Store<AppState, Action> = storeFactory.rootStore()

```

MainQueue is not available for Stores any more.
Since now, stores always operate on a global serial queue with configurable QoS.

## 2. Update actions interceptor and pass in to store factory:

Before:

```swift

rootStore.interceptActions { action in
guard let action = ($0 as? AsyncAppAction) else {
return
}

DispatchQueue.main.async {
action.execute { store.dispatch($0) }
}
}

```

Now:

```swift
let storeFactory = StoreFactory<AppState, Action>(
initialState: initialState,
interceptor: { action, dispatched in
guard let action = ($0 as? AsyncAppAction) else {
return
}

DispatchQueue.main.async {
action.execute { dispatch($0) }
}
},
reducer: reducer
)

```
## 3. Migrate from `proxy(...)` to `scope(...)`:

Before:

```swift
let storeProxy = rootStore.store().proxy { appState in appState.subState }

```

Now:

```swift
let scopeStore = storeFactory.scopeStore { appState in appState.subState }

```

## PureduxSwiftUI Bindings Migration Guide


1. Migrate to from `RootStore` to `StoreFactory` like mentioned in PureduxStore [docs](https://github.com/KazaiMazai/PureduxStore)

Before:

```swift
let appState = AppState()
let rootStore = RootStore<AppState, Action>(initialState: appState, reducer: reducer)
let rootEnvStore = RootEnvStore(rootStore: rootStore)
let fancyFeatureStore = rootEnvStore.store().proxy { $0.yourFancyFeatureSubstate }

let presenter = FancyViewPresenter()

```

Now:

```swift
let appState = AppState()
let storeFactory = StoreFactory<AppState, Action>(initialState: state, reducer: reducer)
let envStoreFactory = EnvStoreFactory(storeFactory: storeFactory)
let fancyFeatureStore = envStoreFactory.scopeStore { $0.yourFancyFeatureSubstate }

let presenter = FancyViewPresenter()

```
2. Migrate from `StoreProvidingView` to `ViewWithStoreFactory` in case your implementation relied on injected `RootEnvStore`

Before:

```swift
UIHostingController(
rootView: StoreProvidingView(rootStore: rootEnvStore) {

//content view
}
)
```

Now:

```swift
UIHostingController(
rootView: ViewWithStoreFactory(envStoreFactory) {

//content view
}
)
```


3. Migrate from `View.with(...)` extension to `ViewWithStore(...)`in case your implementation relied on explicit store

Before:

```swift

FancyView.with(
store: fancyFeatureStore,
removeStateDuplicates: .equal {
$0.title
},
props: presenter.makeProps,
queue: .main,
content: { FancyView(props: $0) }
)
```

Now:

```swift
ViewWithStore(props: presenter.makeProps) {
FancyView(props: $0)
}
.usePresentationQueue(.main)
.removeStateDuplicates(.equal { $0.title })
.store(fancyFeatureStore)

```

4. Migrate from `View.withEnvStore(...)` extension to `ViewWithStore(...)` in case your implementation relied on injected `RootEnvStore`

Before:

```swift

FancyView.withEnvStore(
removeStateDuplicates: .equal {
$0.title
},
props: presenter.makeProps,
queue: .main,
content: { FancyView(props: $0) }
)
```
Now:

```swift
ViewWithStore(props: presenter.makeProps) {
FancyView(props: $0)
}
.usePresentationQueue(.main)
.removeStateDuplicates(.equal { $0.title })


```

## PureduxUIKit Bindings Migration Guide

Nothing needs to be changed.
Loading

0 comments on commit ddb23b4

Please sign in to comment.