Skip to content

Commit a611f14

Browse files
authored
Standups -> SyncUps (#2524)
* Standups -> SyncUps * wip * wip * wip * wip * wip * wip * wip * wip * wip
1 parent bd6c1fc commit a611f14

File tree

46 files changed

+406
-407
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+406
-407
lines changed

ComposableArchitecture.xcworkspace/contents.xcworkspacedata

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Examples/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This directory holds many case studies and applications to demonstrate solving v
1111
* **Speech Recognition**
1212
<br> This application uses Apple's Speech framework to demonstrate how to wrap complex dependencies in the `Effect` type of the Composable Architecture. Doing a little bit of upfront work allows you to interact with the dependencies in a controlled, understandable way, and you can write tests on how the dependency interacts with your application logic.
1313

14-
* **Standups**
14+
* **SyncUps**
1515
<br> This application is a faithful reconstruction of one of Apple's more interesting sample projects, called [Scrumdinger][scrumdinger]. It deals with many forms of navigation (alerts, sheets, drill-downs) and many forms of side effects (data persistence, timers and speech recognizers).
1616

1717
* **Tic-Tac-Toe**
@@ -23,4 +23,4 @@ This directory holds many case studies and applications to demonstrate solving v
2323
* **Voice Memos**
2424
<br> A more complex demo that demonstrates how to work with many complex dependencies at once, and how to manage a complex state machine driven off of timers.
2525

26-
[scrumdinger]: https://developer.apple.com/tutorials/app-dev-training/getting-started-with-scrumdinger
26+
[scrumdinger]: https://developer.apple.com/tutorials/app-dev-training/getting-started-with-scrumdinger

Examples/Standups/README.md renamed to Examples/SyncUps/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Standups
1+
# SyncUps
22

33
This project demonstrates how to build a complex, real world application that deals with many forms
44
of navigation (_e.g._, sheets, drill-downs, alerts), many side effects (timers, speech recognizer,
@@ -27,14 +27,14 @@ But, the simplicity of Apple's Scrumdinger codebase is not a defect. In fact, it
2727
Apple's sample code is viewed by hundreds of thousands of developers across the world, and so its
2828
goal is to be as approachable as possible in order to teach the basics of SwiftUI. But, that doesn't mean there isn't room for improvement.
2929

30-
## Composable Standups
30+
## Composable SyncUps
3131

32-
Our Standups application is a rebuild of Apple's Scrumdinger application, but with a focus on
32+
Our SyncUps application is a rebuild of Apple's Scrumdinger application, but with a focus on
3333
modern, best practices for SwiftUI development. We faithfully recreate the Scrumdinger, but with
3434
some key additions:
3535

3636
1. Identifiers are made type safe using our [Tagged library][tagged-gh]. This prevents us from
37-
writing nonsensical code, such as comparing a `Standup.ID` to a `Attendee.ID`.
37+
writing nonsensical code, such as comparing a `SyncUp.ID` to a `Attendee.ID`.
3838
2. Instead of using bare arrays in feature logic we use an "identified" array from our
3939
[IdentifiedCollections][identified-collections-gh] library. This allows you to read and modify
4040
elements of the collection via their ID rather than positional index, which can be error-prone
@@ -53,8 +53,8 @@ some key additions:
5353
[Dependencies][dependencies-gh] library.
5454
6. The project includes a full test suite. Since all of navigation is driven off of state, and
5555
because we controlled all dependencies, we can write very comprehensive and nuanced tests. For
56-
example, we can write a unit test that proves that when a standup meeting's timer runs out the
57-
screen pops off the stack and a new transcript is added to the standup. Such a test would be
56+
example, we can write a unit test that proves that when a sync-up meeting's timer runs out the
57+
screen pops off the stack and a new transcript is added to the sync-up. Such a test would be
5858
very difficult, if not impossible, without controlling dependencies.
5959

6060
[scrumdinger]: https://developer.apple.com/tutorials/app-dev-training/getting-started-with-scrumdinger

Examples/Standups/Standups.xcodeproj/project.pbxproj renamed to Examples/SyncUps/SyncUps.xcodeproj/project.pbxproj

Lines changed: 80 additions & 80 deletions
Large diffs are not rendered by default.

Examples/Standups/Standups.xcodeproj/xcshareddata/xcschemes/Standups.xcscheme renamed to Examples/SyncUps/SyncUps.xcodeproj/xcshareddata/xcschemes/SyncUps.xcscheme

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<BuildableReference
1616
BuildableIdentifier = "primary"
1717
BlueprintIdentifier = "DC808D6E29E9C3AC0072B4A9"
18-
BuildableName = "Standups.app"
19-
BlueprintName = "Standups"
20-
ReferencedContainer = "container:Standups.xcodeproj">
18+
BuildableName = "SyncUps.app"
19+
BlueprintName = "SyncUps"
20+
ReferencedContainer = "container:SyncUps.xcodeproj">
2121
</BuildableReference>
2222
</BuildActionEntry>
2323
</BuildActionEntries>
@@ -34,19 +34,19 @@
3434
<BuildableReference
3535
BuildableIdentifier = "primary"
3636
BlueprintIdentifier = "DC808D7E29E9C3AD0072B4A9"
37-
BuildableName = "StandupsTests.xctest"
38-
BlueprintName = "StandupsTests"
39-
ReferencedContainer = "container:Standups.xcodeproj">
37+
BuildableName = "SyncUpsTests.xctest"
38+
BlueprintName = "SyncUpsTests"
39+
ReferencedContainer = "container:SyncUps.xcodeproj">
4040
</BuildableReference>
4141
</TestableReference>
4242
<TestableReference
4343
skipped = "NO">
4444
<BuildableReference
4545
BuildableIdentifier = "primary"
4646
BlueprintIdentifier = "DC808D8829E9C3AD0072B4A9"
47-
BuildableName = "StandupsUITests.xctest"
48-
BlueprintName = "StandupsUITests"
49-
ReferencedContainer = "container:Standups.xcodeproj">
47+
BuildableName = "SyncUpsUITests.xctest"
48+
BlueprintName = "SyncUpsUITests"
49+
ReferencedContainer = "container:SyncUps.xcodeproj">
5050
</BuildableReference>
5151
</TestableReference>
5252
</Testables>
@@ -66,9 +66,9 @@
6666
<BuildableReference
6767
BuildableIdentifier = "primary"
6868
BlueprintIdentifier = "DC808D6E29E9C3AC0072B4A9"
69-
BuildableName = "Standups.app"
70-
BlueprintName = "Standups"
71-
ReferencedContainer = "container:Standups.xcodeproj">
69+
BuildableName = "SyncUps.app"
70+
BlueprintName = "SyncUps"
71+
ReferencedContainer = "container:SyncUps.xcodeproj">
7272
</BuildableReference>
7373
</BuildableProductRunnable>
7474
</LaunchAction>
@@ -83,9 +83,9 @@
8383
<BuildableReference
8484
BuildableIdentifier = "primary"
8585
BlueprintIdentifier = "DC808D6E29E9C3AC0072B4A9"
86-
BuildableName = "Standups.app"
87-
BlueprintName = "Standups"
88-
ReferencedContainer = "container:Standups.xcodeproj">
86+
BuildableName = "SyncUps.app"
87+
BlueprintName = "SyncUps"
88+
ReferencedContainer = "container:SyncUps.xcodeproj">
8989
</BuildableReference>
9090
</BuildableProductRunnable>
9191
</ProfileAction>

Examples/Standups/Standups/App.swift renamed to Examples/SyncUps/SyncUps/App.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import ComposableArchitecture
22
import SwiftUI
33

44
@main
5-
struct StandupsApp: App {
5+
struct SyncUpsApp: App {
66
var body: some Scene {
77
WindowGroup {
88
// NB: This conditional is here only to facilitate UI testing so that we can mock out certain

Examples/Standups/Standups/AppFeature.swift renamed to Examples/SyncUps/SyncUps/AppFeature.swift

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import SwiftUI
44
struct AppFeature: Reducer {
55
struct State: Equatable {
66
var path = StackState<Path.State>()
7-
var standupsList = StandupsList.State()
7+
var syncUpsList = SyncUpsList.State()
88
}
99

1010
enum Action: Equatable {
1111
case path(StackAction<Path.State, Path.Action>)
12-
case standupsList(StandupsList.Action)
12+
case syncUpsList(SyncUpsList.Action)
1313
}
1414

1515
@Dependency(\.continuousClock) var clock
@@ -22,8 +22,8 @@ struct AppFeature: Reducer {
2222
}
2323

2424
var body: some ReducerOf<Self> {
25-
Scope(state: \.standupsList, action: /Action.standupsList) {
26-
StandupsList()
25+
Scope(state: \.syncUpsList, action: /Action.syncUpsList) {
26+
SyncUpsList()
2727
}
2828
Reduce { state, action in
2929
switch action {
@@ -32,16 +32,16 @@ struct AppFeature: Reducer {
3232
else { return .none }
3333

3434
switch delegateAction {
35-
case .deleteStandup:
36-
state.standupsList.standups.remove(id: detailState.standup.id)
35+
case .deleteSyncUp:
36+
state.syncUpsList.syncUps.remove(id: detailState.syncUp.id)
3737
return .none
3838

39-
case let .standupUpdated(standup):
40-
state.standupsList.standups[id: standup.id] = standup
39+
case let .syncUpUpdated(syncUp):
40+
state.syncUpsList.syncUps[id: syncUp.id] = syncUp
4141
return .none
4242

4343
case .startMeeting:
44-
state.path.append(.record(RecordMeeting.State(standup: detailState.standup)))
44+
state.path.append(.record(RecordMeeting.State(syncUp: detailState.syncUp)))
4545
return .none
4646
}
4747

@@ -58,24 +58,24 @@ struct AppFeature: Reducer {
5858
return .none
5959
}
6060

61-
state.path[id: id, case: /Path.State.detail]?.standup.meetings.insert(
61+
state.path[id: id, case: /Path.State.detail]?.syncUp.meetings.insert(
6262
Meeting(
6363
id: Meeting.ID(self.uuid()),
6464
date: self.now,
6565
transcript: transcript
6666
),
6767
at: 0
6868
)
69-
guard let standup = state.path[id: id, case: /Path.State.detail]?.standup
69+
guard let syncUp = state.path[id: id, case: /Path.State.detail]?.syncUp
7070
else { return .none }
71-
state.standupsList.standups[id: standup.id] = standup
71+
state.syncUpsList.syncUps[id: syncUp.id] = syncUp
7272
return .none
7373
}
7474

7575
case .path:
7676
return .none
7777

78-
case .standupsList:
78+
case .syncUpsList:
7979
return .none
8080
}
8181
}
@@ -84,10 +84,10 @@ struct AppFeature: Reducer {
8484
}
8585

8686
Reduce { state, action in
87-
return .run { [standups = state.standupsList.standups] _ in
87+
return .run { [syncUps = state.syncUpsList.syncUps] _ in
8888
try await withTaskCancellation(id: CancelID.saveDebounce, cancelInFlight: true) {
8989
try await self.clock.sleep(for: .seconds(1))
90-
try await self.saveData(JSONEncoder().encode(standups), .standups)
90+
try await self.saveData(JSONEncoder().encode(syncUps), .syncUps)
9191
}
9292
} catch: { _, _ in
9393
}
@@ -96,19 +96,19 @@ struct AppFeature: Reducer {
9696

9797
struct Path: Reducer {
9898
enum State: Equatable {
99-
case detail(StandupDetail.State)
100-
case meeting(Meeting, standup: Standup)
99+
case detail(SyncUpDetail.State)
100+
case meeting(Meeting, syncUp: SyncUp)
101101
case record(RecordMeeting.State)
102102
}
103103

104104
enum Action: Equatable {
105-
case detail(StandupDetail.Action)
105+
case detail(SyncUpDetail.Action)
106106
case record(RecordMeeting.Action)
107107
}
108108

109109
var body: some Reducer<State, Action> {
110110
Scope(state: /State.detail, action: /Action.detail) {
111-
StandupDetail()
111+
SyncUpDetail()
112112
}
113113
Scope(state: /State.record, action: /Action.record) {
114114
RecordMeeting()
@@ -122,19 +122,19 @@ struct AppView: View {
122122

123123
var body: some View {
124124
NavigationStackStore(self.store.scope(state: \.path, action: { .path($0) })) {
125-
StandupsListView(
126-
store: self.store.scope(state: \.standupsList, action: { .standupsList($0) })
125+
SyncUpsListView(
126+
store: self.store.scope(state: \.syncUpsList, action: { .syncUpsList($0) })
127127
)
128128
} destination: {
129129
switch $0 {
130130
case .detail:
131131
CaseLet(
132132
/AppFeature.Path.State.detail,
133133
action: AppFeature.Path.Action.detail,
134-
then: StandupDetailView.init(store:)
134+
then: SyncUpDetailView.init(store:)
135135
)
136-
case let .meeting(meeting, standup: standup):
137-
MeetingView(meeting: meeting, standup: standup)
136+
case let .meeting(meeting, syncUp: syncUp):
137+
MeetingView(meeting: meeting, syncUp: syncUp)
138138
case .record:
139139
CaseLet(
140140
/AppFeature.Path.State.record,
@@ -147,5 +147,5 @@ struct AppView: View {
147147
}
148148

149149
extension URL {
150-
static let standups = Self.documentsDirectory.appending(component: "standups.json")
150+
static let syncUps = Self.documentsDirectory.appending(component: "sync-ups.json")
151151
}

0 commit comments

Comments
 (0)