Skip to content

Commit e79c0ac

Browse files
committed
Update README
1 parent 4b5df29 commit e79c0ac

File tree

2 files changed

+58
-40
lines changed

2 files changed

+58
-40
lines changed

README.md

Lines changed: 58 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
- [KeepAlive](#keepalive)
2828
- [Suspense](#suspense)
2929
- [Testing](#testing)
30+
- [Debugging](#debugging)
3031
- [Preview](#preview)
31-
- [Observability](#observability)
3232
- [Advanced Usage](#advanced-usage)
3333
- [Dealing with Known SwiftUI Bugs](#dealing-with-known-swiftui-bugs)
3434
- [Contributing](#contributing)
@@ -1212,57 +1212,75 @@ class FetchBookTests: XCTestCase {
12121212

12131213
---
12141214

1215-
### Preview
1215+
### Debugging
12161216

1217-
Even in SwiftUI previews, the view must have an `AtomRoot` somewhere in the ancestor. However, since This library offers the new solution for dependency injection, you don't need to do painful DI each time you create previews anymore. You can to override the atoms that you really want to inject substitutions.
1217+
This library defines a Directed Acyclic Graph (DAG) internally to centrally manage atom states, making it easy to analyze its dependencies and where they are (or are not) being used.
1218+
There are the following two ways to get a [Snapshot](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/snapshot) of the dependency graph at a given point in time.
1219+
1220+
The first is to get `Snapshot` through [@ViewContext](#atomviewcontext). This API is suitable for obtaining and analyzing debugging information on demand.
12181221

12191222
```swift
1220-
struct NewsList_Preview: PreviewProvider {
1221-
static var previews: some View {
1222-
AtomRoot {
1223-
NewsList()
1224-
}
1225-
.override(APIClientAtom()) { _ in
1226-
StubAPIClient()
1227-
}
1223+
@ViewContext
1224+
var context
1225+
1226+
var debugButton: some View {
1227+
Button("Dump dependency graph") {
1228+
let snapshot = context.snapshot()
1229+
print(snapshot.graphDescription())
12281230
}
12291231
}
12301232
```
12311233

1232-
---
1234+
Or, you can observe all updates of atoms and always continue to receive `Snapshots` at that point in time through `observe(_:)` modifier of [AtomRoot](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomroot) or [AtomRelay](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomrelay).
1235+
Note that observing in `AtomRoot` will receive all atom updates that happened in the whole app, but observing in `AtomRelay` will only receive atoms used in the descendant views.
12331236

1234-
### Observability
1237+
```swift
1238+
AtomRoot {
1239+
HomeScreen()
1240+
}
1241+
.observe { snapshot in
1242+
print(snapshot.graphDescription())
1243+
}
1244+
```
12351245

1236-
For debugging, you can observe updates with a snapshot that captures a specific set of values of atoms through the `observe(_:)` function in [AtomRoot](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomroot) or [AtomRelay](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomrelay).
1237-
Observing in `AtomRoot` will receive all atom updates that happened in the whole app, but observing in `AtomRelay` will only receive atoms used in the descendant views.
1246+
Calling the [restore()](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/snapshot/restore()) method of the obtained `Snapshot` will roll back to the states and dependency graph at that point in time to see what happened.
1247+
The debugging technique is called [time travel debugging](https://en.wikipedia.org/wiki/Time_travel_debugging), and the example application [here](Examples/Packages/iOS/Sources/ExampleTimeTravel) demonstrates how it works.
12381248

1239-
The [Snapshot](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/snapshot) passed to `observe(:_)` has a [restore()](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/snapshot/restore()) function that can be executed to restore a specific set of atom values. `Snapshot` can also be obtained on-demand through [AtomViewContext](#atomviewcontext).
1240-
This observability API can be applied to do [time travel debugging](https://en.wikipedia.org/wiki/Time_travel_debugging) and is demonstrated in one of the [examples](Examples).
1249+
In addition, [graphDescription()](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/snapshot/graphdescription()) method returns a string, that represents the dependencies graph and where they are used, as a String in [graph description language DOT](https://graphviz.org/doc/info/lang.html).
1250+
This can be converted to an image using [Graphviz](https://graphviz.org), a graph visualization tool, to visually analyze information about the state of the application, as shown below.
12411251

1242-
```swift
1243-
@main
1244-
struct ExampleApp: App {
1245-
var body: some Scene {
1246-
WindowGroup {
1247-
AtomRoot {
1248-
VStack {
1249-
NavigationLink("Home") {
1250-
Home()
1251-
}
1252+
<img src="assets/dependency_graph.png" alt="Dependency Graph" width="50%" align="right">
12521253

1253-
NavigationLink("Setting") {
1254-
AtomRelay {
1255-
Setting()
1256-
}
1257-
.observe { snapshot in // Observes setting related atoms only.
1258-
print(snapshot)
1259-
}
1260-
}
1261-
}
1262-
}
1263-
.observe { snapshot in // Observes all atoms used in the app.
1264-
print(snapshot)
1265-
}
1254+
```dot
1255+
digraph {
1256+
node [shape=box]
1257+
"FilterAtom"
1258+
"FilterAtom" -> "TodoApp/FilterPicker.swift" [label="line:3"]
1259+
"FilterAtom" -> "FilteredTodosAtom"
1260+
"TodosAtom"
1261+
"TodosAtom" -> "FilteredTodosAtom"
1262+
"TodosAtom" -> "StatsAtom"
1263+
"FilteredTodosAtom"
1264+
"FilteredTodosAtom" -> "TodoApp/TodoList.swift" [label="line:5"]
1265+
"TodoApp/TodoList.swift" [style=filled]
1266+
"TodoApp/FilterPicker.swift" [style=filled]
1267+
}
1268+
```
1269+
1270+
---
1271+
1272+
### Preview
1273+
1274+
Even in SwiftUI previews, the view must have an `AtomRoot` somewhere in the ancestor. However, since This library offers the new solution for dependency injection, you don't need to do painful DI each time you create previews anymore. You can to override the atoms that you really want to inject substitutions.
1275+
1276+
```swift
1277+
struct NewsList_Preview: PreviewProvider {
1278+
static var previews: some View {
1279+
AtomRoot {
1280+
NewsList()
1281+
}
1282+
.override(APIClientAtom()) { _ in
1283+
StubAPIClient()
12661284
}
12671285
}
12681286
}

assets/dependency_graph.png

15.2 KB
Loading

0 commit comments

Comments
 (0)