Skip to content

Commit 4406349

Browse files
authored
Deprecate old alert APIs in favor of new presentation APIs (#2335)
* Deprecate old alert APIs in favor of new presentation APIs * wip * wip * wip
1 parent 37b8a41 commit 4406349

File tree

4 files changed

+84
-65
lines changed

4 files changed

+84
-65
lines changed

Examples/CaseStudies/SwiftUICaseStudies/01-GettingStarted-AlertsAndConfirmationDialogs.swift

Lines changed: 66 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -23,73 +23,82 @@ private let readMe = """
2323

2424
struct AlertAndConfirmationDialog: Reducer {
2525
struct State: Equatable {
26-
var alert: AlertState<Action>?
27-
var confirmationDialog: ConfirmationDialogState<Action>?
26+
@PresentationState var alert: AlertState<Action.Alert>?
27+
@PresentationState var confirmationDialog: ConfirmationDialogState<Action.ConfirmationDialog>?
2828
var count = 0
2929
}
3030

3131
enum Action: Equatable {
32+
case alert(PresentationAction<Alert>)
3233
case alertButtonTapped
33-
case alertDismissed
34+
case confirmationDialog(PresentationAction<ConfirmationDialog>)
3435
case confirmationDialogButtonTapped
35-
case confirmationDialogDismissed
36-
case decrementButtonTapped
37-
case incrementButtonTapped
36+
37+
enum Alert: Equatable {
38+
case incrementButtonTapped
39+
}
40+
enum ConfirmationDialog: Equatable {
41+
case incrementButtonTapped
42+
case decrementButtonTapped
43+
}
3844
}
3945

40-
func reduce(into state: inout State, action: Action) -> Effect<Action> {
41-
switch action {
42-
case .alertButtonTapped:
43-
state.alert = AlertState {
44-
TextState("Alert!")
45-
} actions: {
46-
ButtonState(role: .cancel) {
47-
TextState("Cancel")
48-
}
49-
ButtonState(action: .incrementButtonTapped) {
50-
TextState("Increment")
51-
}
52-
} message: {
53-
TextState("This is an alert")
54-
}
55-
return .none
56-
57-
case .alertDismissed:
58-
state.alert = nil
59-
return .none
60-
61-
case .confirmationDialogButtonTapped:
62-
state.confirmationDialog = ConfirmationDialogState {
63-
TextState("Confirmation dialog")
64-
} actions: {
65-
ButtonState(role: .cancel) {
66-
TextState("Cancel")
67-
}
68-
ButtonState(action: .incrementButtonTapped) {
69-
TextState("Increment")
46+
var body: some Reducer<State, Action> {
47+
Reduce { state, action in
48+
switch action {
49+
case .alert(.presented(.incrementButtonTapped)),
50+
.confirmationDialog(.presented(.incrementButtonTapped)):
51+
state.alert = AlertState { TextState("Incremented!") }
52+
state.count += 1
53+
return .none
54+
55+
case .alert:
56+
return .none
57+
58+
case .alertButtonTapped:
59+
state.alert = AlertState {
60+
TextState("Alert!")
61+
} actions: {
62+
ButtonState(role: .cancel) {
63+
TextState("Cancel")
64+
}
65+
ButtonState(action: .incrementButtonTapped) {
66+
TextState("Increment")
67+
}
68+
} message: {
69+
TextState("This is an alert")
7070
}
71-
ButtonState(action: .decrementButtonTapped) {
72-
TextState("Decrement")
71+
return .none
72+
73+
case .confirmationDialog(.presented(.decrementButtonTapped)):
74+
state.alert = AlertState { TextState("Decremented!") }
75+
state.count -= 1
76+
return .none
77+
78+
case .confirmationDialog:
79+
return .none
80+
81+
case .confirmationDialogButtonTapped:
82+
state.confirmationDialog = ConfirmationDialogState {
83+
TextState("Confirmation dialog")
84+
} actions: {
85+
ButtonState(role: .cancel) {
86+
TextState("Cancel")
87+
}
88+
ButtonState(action: .incrementButtonTapped) {
89+
TextState("Increment")
90+
}
91+
ButtonState(action: .decrementButtonTapped) {
92+
TextState("Decrement")
93+
}
94+
} message: {
95+
TextState("This is a confirmation dialog.")
7396
}
74-
} message: {
75-
TextState("This is a confirmation dialog.")
97+
return .none
7698
}
77-
return .none
78-
79-
case .confirmationDialogDismissed:
80-
state.confirmationDialog = nil
81-
return .none
82-
83-
case .decrementButtonTapped:
84-
state.alert = AlertState { TextState("Decremented!") }
85-
state.count -= 1
86-
return .none
87-
88-
case .incrementButtonTapped:
89-
state.alert = AlertState { TextState("Incremented!") }
90-
state.count += 1
91-
return .none
9299
}
100+
.ifLet(\.$alert, action: /Action.alert)
101+
.ifLet(\.$confirmationDialog, action: /Action.confirmationDialog)
93102
}
94103
}
95104

@@ -112,12 +121,10 @@ struct AlertAndConfirmationDialogView: View {
112121
}
113122
.navigationTitle("Alerts & Dialogs")
114123
.alert(
115-
self.store.scope(state: \.alert, action: { $0 }),
116-
dismiss: .alertDismissed
124+
store: self.store.scope(state: \.$alert, action: { .alert($0) })
117125
)
118126
.confirmationDialog(
119-
self.store.scope(state: \.confirmationDialog, action: { $0 }),
120-
dismiss: .confirmationDialogDismissed
127+
store: self.store.scope(state: \.$confirmationDialog, action: { .confirmationDialog($0) })
121128
)
122129
}
123130
}

Examples/CaseStudies/SwiftUICaseStudiesTests/01-GettingStarted-AlertsAndConfirmationDialogsTests.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ final class AlertsAndConfirmationDialogsTests: XCTestCase {
2424
TextState("This is an alert")
2525
}
2626
}
27-
await store.send(.incrementButtonTapped) {
27+
await store.send(.alert(.presented(.incrementButtonTapped))) {
2828
$0.alert = AlertState { TextState("Incremented!") }
2929
$0.count = 1
3030
}
31-
await store.send(.alertDismissed) {
31+
await store.send(.alert(.dismiss)) {
3232
$0.alert = nil
3333
}
3434
}
@@ -55,12 +55,10 @@ final class AlertsAndConfirmationDialogsTests: XCTestCase {
5555
TextState("This is a confirmation dialog.")
5656
}
5757
}
58-
await store.send(.incrementButtonTapped) {
58+
await store.send(.confirmationDialog(.presented(.incrementButtonTapped))) {
5959
$0.alert = AlertState { TextState("Incremented!") }
60-
$0.count = 1
61-
}
62-
await store.send(.confirmationDialogDismissed) {
6360
$0.confirmationDialog = nil
61+
$0.count = 1
6462
}
6563
}
6664
}

Sources/ComposableArchitecture/SwiftUI/Alert.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ extension View {
6262
}
6363
}
6464

65+
@available(
66+
*,
67+
deprecated,
68+
message: """
69+
Use 'View.alert(store:)' with 'PresentationState' and 'PresentationAction' instead, or use 'Alert.init(state:)' to create an alert in iOS 13.
70+
"""
71+
)
6572
extension View {
6673
/// Displays an alert when then store's state becomes non-`nil`, and dismisses it when it becomes
6774
/// `nil`.

Sources/ComposableArchitecture/SwiftUI/ConfirmationDialog.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ extension View {
6767
}
6868
}
6969

70+
@available(
71+
*,
72+
deprecated,
73+
message: """
74+
Use 'View.confirmationDialog(store:)' with 'PresentationState' and 'PresentationAction' instead, or use 'ActionSheet.init(state:)' to create a confirmation dialog in iOS 13.
75+
"""
76+
)
7077
extension View {
7178
/// Displays a dialog when the store's state becomes non-`nil`, and dismisses it when it becomes
7279
/// `nil`.

0 commit comments

Comments
 (0)