Skip to content

Commit 330123c

Browse files
authored
Obsolete Coordinator (#136)
* Obsolete Coordinator * Update README
1 parent abd82f2 commit 330123c

36 files changed

+160
-464
lines changed

Examples/Packages/iOS/Sources/ExampleMap/Atoms.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,18 @@ final class LocationObserver: NSObject, ObservableObject, CLLocationManagerDeleg
3737
}
3838
}
3939

40-
struct LocationObserverAtom: ObservableObjectAtom, Hashable {
41-
func makeCoordinator() -> LocationManagerProtocol {
40+
struct LocationManagerAtom: ValueAtom, Hashable {
41+
func value(context: Context) -> LocationManagerProtocol {
4242
let manager = CLLocationManager()
4343
manager.desiredAccuracy = kCLLocationAccuracyBest
4444
return manager
4545
}
46+
}
4647

48+
struct LocationObserverAtom: ObservableObjectAtom, Hashable {
4749
func object(context: Context) -> LocationObserver {
48-
LocationObserver(manager: context.coordinator)
50+
let manager = context.watch(LocationManagerAtom())
51+
return LocationObserver(manager: manager)
4952
}
5053
}
5154

README.md

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
- [Basic Tutorial](#basic-tutorial)
2121
- [Guides](#guides)
2222
- [AtomRoot](#atomroot)
23-
- [Atoms](#atoms-1)
24-
- [Modifiers](#modifiers)
25-
- [Attributes](#attributes)
26-
- [Property Wrappers](#property-wrappers)
23+
- [Atom](#atom)
24+
- [Modifier](#modifier)
25+
- [Attribute](#attribute)
26+
- [Property Wrapper](#property-wrapper)
2727
- [Context](#context)
28-
- [Views](#views)
28+
- [View](#view)
2929
- [Techniques](#techniques)
3030
- [Advanced Usage](#advanced-usage)
3131
- [Dealing with Known SwiftUI Bugs](#dealing-with-known-swiftui-bugs)
@@ -365,7 +365,7 @@ struct ExampleApp: App {
365365

366366
---
367367

368-
### Atoms
368+
### Atom
369369

370370
An atom represents a piece of state and is the source of truth for your app. It can also represent a derived data by combining and transforming one or more other atoms.
371371
Each atom does not actually have a global data inside, and retrieve values from the store provided by the `AtomRoot`. That's why *they can be accessed from anywhere, but never lose testability.*
@@ -630,7 +630,7 @@ struct ContactView: View {
630630

631631
---
632632

633-
### Modifiers
633+
### Modifier
634634

635635
Modifiers can be applied to an atom to produce a different versions of the original atom to make it more coding friendly or to reduce view re-computation for performance optimization.
636636

@@ -735,7 +735,7 @@ struct WeatherReportView: View {
735735

736736
---
737737

738-
### Attributes
738+
### Attribute
739739

740740
The attributes allow control over how the atoms essentially work, for example, cache control of the state.
741741

@@ -856,7 +856,7 @@ private struct RandomNumberGeneratorAtom: ValueAtom, Hashable {
856856

857857
---
858858

859-
### Property Wrappers
859+
### Property Wrapper
860860

861861
The following property wrappers are used to bind atoms to view and recompute the view with data changes.
862862
By retrieving the atom through these property wrappers, the internal system marks the atom as in-use and the values are cached until that view is dismantled.
@@ -1022,24 +1022,23 @@ Context is a structure for using and interacting with atom values from views or
10221022

10231023
|API|Use|
10241024
|:--|:--|
1025-
|[watch](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomwatchablecontext/watch(_:))|Obtains an atom value and starts watching its update.|
1026-
|[read](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/read(_:))|Obtains an atom value but does not watch its update.|
1027-
|[set](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/set(_:for:))|Sets a new value to the atom.|
1028-
|[modify](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/modify(_:body:))|Modifies the cached atom value.|
1025+
|[watch(_:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomtestcontext/watch(_:))|Gets an atom value and starts watching its update.|
1026+
|[read(_:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/read(_:))|Gets an atom value but does not watch its update.|
1027+
|[set(_:for:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/set(_:for:))|Sets a new value to the atom.|
1028+
|[modify(_:body:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/modify(_:body:))|Modifies the cached atom value.|
10291029
|[subscript[]](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/subscript(_:))|Read-write access for applying mutating methods.|
1030-
|[refresh](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/refresh(_:)-1gb3a)|Produce a new value of the atom after waiting until asynchronous operation is complete.|
1031-
|[reset](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/reset(_:))|Reset an atom to the default value or a first output.|
1030+
|[refresh(_:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/refresh(_:)-1gb3a)|Produce a new value of the atom after waiting until asynchronous operation is complete.|
1031+
|[reset(_:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomcontext/reset(_:))|Reset an atom to the default value or a first output.|
10321032

1033-
There are the following types context as different contextual environments.
1034-
The APIs described in each section below are their own specific functionality depending on the environment in which it is used, in addition to the above common APIs.
1033+
Contexts are provided in the following types depending on the environment where they are provided. In addition to the common APIs described above, each context type may have its unique functionalities.
10351034

10361035
#### [AtomViewContext](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomviewcontext)
10371036

10381037
A context available through the `@ViewContext` property wrapper when using atoms from a view.
10391038

10401039
|API|Use|
10411040
|:--|:--|
1042-
|[binding](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomviewcontext/binding(_:))|Gets a binding to the atom state.|
1041+
|[binding(_:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomviewcontext/binding(_:))|Gets a binding to the atom state.|
10431042
|[snapshot()](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomviewcontext/snapshot())|For debugging, takes a snapshot that captures specific set of values of atoms.|
10441043

10451044
<details><summary><code>📖 Example</code></summary>
@@ -1117,35 +1116,26 @@ struct BooksView: View {
11171116
#### [AtomTransactionContext](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomtransactioncontext)
11181117

11191118
A context passed as a parameter to the primary function of each atom type.
1120-
This context type has a `coordinator` property that preserves an instance from the time an atom is used and initialized until it is unused and cleaned up, so it can be used to cache values or as a lifecycle for an atom.
1121-
1122-
|API|Use|
1123-
|:--|:--|
1124-
|[coordinator](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomtransactioncontext/coordinator)|The atom’s associated coordinator that preservess a state until the atom will no longer be used.|
11251119

11261120
<details><summary><code>📖 Example</code></summary>
11271121

11281122
```swift
1129-
struct LocationManagerAtom: ValueAtom, Hashable {
1130-
final class Coordinator: NSObject, CLLocationManagerDelegate { ... }
1123+
final class LocationManagerDelegate: NSObject, CLLocationManagerDelegate { ... }
11311124

1132-
func makeCoordinator() -> Coordinator {
1133-
Coordinator()
1125+
struct LocationManagerDelegateAtom: ValueAtom, Hashable {
1126+
func value(context: Context) -> LocationManagerDelegate {
1127+
LocationManagerDelegate()
11341128
}
1129+
}
11351130

1131+
struct LocationManagerAtom: ValueAtom, Hashable {
11361132
func value(context: Context) -> LocationManagerProtocol {
1133+
let delegate = context.watch(LocationManagerDelegateAtom())
11371134
let manager = CLLocationManager()
1138-
manager.delegate = context.coordinator
1135+
manager.delegate = delegate
11391136
return manager
11401137
}
11411138
}
1142-
1143-
struct CoordinateAtom: ValueAtom, Hashable {
1144-
func value(context: Context) -> CLLocationCoordinate2D? {
1145-
let manager = context.watch(LocationManagerAtom())
1146-
return manager.location?.coordinate
1147-
}
1148-
}
11491139
```
11501140

11511141
</details>
@@ -1156,6 +1146,7 @@ A context that can simulate any scenarios in which atoms are used from a view or
11561146

11571147
|API|Use|
11581148
|:--|:--|
1149+
|[lookup(_:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomtestcontext/lookup(_:))|Gets an atom value without creating a cache.|
11591150
|[unwatch(_:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomtestcontext/unwatch(_:))|Simulates a scenario in which the atom is no longer watched.|
11601151
|[override(_:with:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomtestcontext/override(_:with:)-40pb3)|Overwrites the output of a specific atom or all atoms of the given type with the fixed value.|
11611152
|[waitForUpdate(timeout:)](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomtestcontext/waitforupdate(timeout:))|Waits until any of the atoms watched through this context have been updated.|
@@ -1205,7 +1196,7 @@ class FetchMusicsTests: XCTestCase {
12051196

12061197
---
12071198

1208-
### Views
1199+
### View
12091200

12101201
#### [AtomScope](https://ra1028.github.io/swiftui-atom-properties/documentation/atoms/atomscope)
12111202

@@ -1249,7 +1240,7 @@ struct NewsView: View {
12491240

12501241
### Techniques
12511242

1252-
#### Scoped Atoms
1243+
#### Scoped Atom
12531244

12541245
This library is designed with the shared state as a single source of truth first principle, but also the state can be scoped depending on the intended use.
12551246
Scoped atoms preserves the atom state in the [AtomScope](#atomscope) nearest to the ancestor of where it is used and prevents it from being shared out of scope. `Scoped` is the attribute for that feature.
@@ -1307,7 +1298,7 @@ AtomScope(id: TextScopeID()) {
13071298
This is also useful when multiple identical screens are stacked and each screen needs isolated states such as user inputs.
13081299
Note that other atoms that depend on scoped atoms will be in a shared state and must be given `Scoped` attribute as well in order to scope them as well.
13091300

1310-
#### Atom Effects
1301+
#### Atom Effect
13111302

13121303
Atom effects are an API for managing side effects that are synchronized with the atom's lifecycle. They are widely applicable for variety of usage such as state synchronization, state persistence, logging, and etc, by observing and reacting to state changes.
13131304

@@ -1370,7 +1361,7 @@ final class CountTimerEffect: AtomEffect {
13701361
}
13711362
```
13721363

1373-
#### Override Atoms
1364+
#### Atom Override
13741365

13751366
You can override atoms in [AtomRoot](#atomroot) or [AtomScope](#atomscope) to overwirete the atom states for dependency injection or faking state in particular view, which is useful especially for testing.
13761367

Sources/Atoms/Atom/AsyncSequenceAtom.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public protocol AsyncSequenceAtom: AsyncAtom where Produced == AsyncPhase<Sequen
6363
}
6464

6565
public extension AsyncSequenceAtom {
66-
var producer: AtomProducer<Produced, Coordinator> {
66+
var producer: AtomProducer<Produced> {
6767
AtomProducer { context in
6868
let sequence = context.transaction(sequence)
6969
let task = Task {
@@ -86,7 +86,7 @@ public extension AsyncSequenceAtom {
8686
}
8787
}
8888

89-
var refreshProducer: AtomRefreshProducer<Produced, Coordinator> {
89+
var refreshProducer: AtomRefreshProducer<Produced> {
9090
AtomRefreshProducer { context in
9191
let sequence = context.transaction(sequence)
9292
let task = Task {

Sources/Atoms/Atom/ObservableObjectAtom.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public protocol ObservableObjectAtom: Atom where Produced == ObjectType {
6666
}
6767

6868
public extension ObservableObjectAtom {
69-
var producer: AtomProducer<Produced, Coordinator> {
69+
var producer: AtomProducer<Produced> {
7070
AtomProducer { context in
7171
context.transaction(object)
7272
} manageValue: { object, context in

Sources/Atoms/Atom/PublisherAtom.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public protocol PublisherAtom: AsyncAtom where Produced == AsyncPhase<Publisher.
5656
}
5757

5858
public extension PublisherAtom {
59-
var producer: AtomProducer<Produced, Coordinator> {
59+
var producer: AtomProducer<Produced> {
6060
AtomProducer { context in
6161
let results = context.transaction(publisher).results
6262
let task = Task {
@@ -72,7 +72,7 @@ public extension PublisherAtom {
7272
}
7373
}
7474

75-
var refreshProducer: AtomRefreshProducer<Produced, Coordinator> {
75+
var refreshProducer: AtomRefreshProducer<Produced> {
7676
AtomRefreshProducer { context in
7777
let results = context.transaction(publisher).results
7878
let task = Task {

Sources/Atoms/Atom/StateAtom.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public protocol StateAtom: Atom {
4444
}
4545

4646
public extension StateAtom {
47-
var producer: AtomProducer<Value, Coordinator> {
47+
var producer: AtomProducer<Value> {
4848
AtomProducer { context in
4949
context.transaction(defaultValue)
5050
}

Sources/Atoms/Atom/TaskAtom.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public protocol TaskAtom: AsyncAtom where Produced == Task<Success, Never> {
5252
}
5353

5454
public extension TaskAtom {
55-
var producer: AtomProducer<Produced, Coordinator> {
55+
var producer: AtomProducer<Produced> {
5656
AtomProducer { context in
5757
Task { [value] in
5858
await context.transaction(value)
@@ -62,7 +62,7 @@ public extension TaskAtom {
6262
}
6363
}
6464

65-
var refreshProducer: AtomRefreshProducer<Produced, Coordinator> {
65+
var refreshProducer: AtomRefreshProducer<Produced> {
6666
AtomRefreshProducer { context in
6767
Task { [value] in
6868
await context.transaction(value)

Sources/Atoms/Atom/ThrowingTaskAtom.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public protocol ThrowingTaskAtom: AsyncAtom where Produced == Task<Success, Erro
5656
}
5757

5858
public extension ThrowingTaskAtom {
59-
var producer: AtomProducer<Produced, Coordinator> {
59+
var producer: AtomProducer<Produced> {
6060
AtomProducer { context in
6161
Task { [value] in
6262
try await context.transaction(value)
@@ -66,7 +66,7 @@ public extension ThrowingTaskAtom {
6666
}
6767
}
6868

69-
var refreshProducer: AtomRefreshProducer<Produced, Coordinator> {
69+
var refreshProducer: AtomRefreshProducer<Produced> {
7070
AtomRefreshProducer { context in
7171
Task { [value] in
7272
try await context.transaction(value)

Sources/Atoms/Atom/ValueAtom.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public protocol ValueAtom: Atom {
4747
}
4848

4949
public extension ValueAtom {
50-
var producer: AtomProducer<Value, Coordinator> {
50+
var producer: AtomProducer<Value> {
5151
AtomProducer { context in
5252
context.transaction(value)
5353
}

Sources/Atoms/Atoms.docc/Atoms.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,11 @@ Building state by compositing atoms automatically optimizes rendering based on i
7575
- ``AtomViewContext``
7676
- ``AtomTestContext``
7777
- ``AtomCurrentContext``
78-
- ``AtomEffectContext``
7978

8079
### Misc
8180

8281
- ``Atom``
8382
- ``AsyncAtom``
84-
- ``AtomPrimitive``
8583
- ``AtomStore``
8684
- ``AtomModifier``
8785
- ``AsyncAtomModifier``

0 commit comments

Comments
 (0)