Skip to content

Commit 6df8198

Browse files
committed
Add @ViewBuilder to ForEachStore and IfLetStore (#501)
* Add @ViewBuilder to ForEachStore and IfLetStore * Update IfLetStore else branch to take view builder
1 parent f847e27 commit 6df8198

File tree

9 files changed

+170
-154
lines changed

9 files changed

+170
-154
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ struct OptionalBasicsView: View {
6969
.buttonStyle(BorderlessButtonStyle())
7070
}
7171
},
72-
else: Text(template: "`CounterState` is `nil`", .body)
72+
else: {
73+
Text(template: "`CounterState` is `nil`", .body)
74+
}
7375
)
7476
}
7577
}

Examples/CaseStudies/SwiftUICaseStudies/03-Navigation-Lists-NavigateAndLoad.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ struct NavigateAndLoadListView: View {
8989
self.store.scope(
9090
state: { $0.selection?.value }, action: NavigateAndLoadListAction.counter),
9191
then: CounterView.init(store:),
92-
else: ActivityIndicator()
92+
else: { ActivityIndicator() }
9393
),
9494
tag: row.id,
9595
selection: viewStore.binding(

Examples/CaseStudies/SwiftUICaseStudies/03-Navigation-NavigateAndLoad.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ struct NavigateAndLoadView: View {
7171
self.store.scope(
7272
state: { $0.optionalCounter }, action: NavigateAndLoadAction.optionalCounter),
7373
then: CounterView.init(store:),
74-
else: ActivityIndicator()
74+
else: { ActivityIndicator() }
7575
),
7676
isActive: viewStore.binding(
7777
get: { $0.isNavigationActive },

Examples/CaseStudies/SwiftUICaseStudies/03-Navigation-Sheet-PresentAndLoad.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ struct PresentAndLoadView: View {
7979
self.store.scope(
8080
state: { $0.optionalCounter }, action: PresentAndLoadAction.optionalCounter),
8181
then: CounterView.init(store:),
82-
else: ActivityIndicator()
82+
else: { ActivityIndicator() }
8383
)
8484
}
8585
.navigationBarTitle("Present and load")

Examples/CaseStudies/UIKitCaseStudies/Internal/IfLetStoreController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ final class IfLetStoreController<State, Action>: UIViewController {
2121
init(
2222
store: Store<State?, Action>,
2323
then ifDestination: @escaping (Store<State, Action>) -> UIViewController,
24-
else elseDestination: @autoclosure @escaping () -> UIViewController
24+
else elseDestination: @escaping () -> UIViewController
2525
) {
2626
self.store = store
2727
self.ifDestination = ifDestination

Examples/CaseStudies/UIKitCaseStudies/NavigateAndLoad.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class EagerNavigationViewController: UIViewController {
8888
store: self.store
8989
.scope(state: { $0.optionalCounter }, action: EagerNavigationAction.optionalCounter),
9090
then: CounterViewController.init(store:),
91-
else: ActivityIndicatorViewController()
91+
else: ActivityIndicatorViewController.init
9292
),
9393
animated: true
9494
)

Sources/ComposableArchitecture/Internal/Deprecations.swift

Lines changed: 84 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,102 @@
11
#if canImport(SwiftUI)
22

3-
import SwiftUI
3+
import SwiftUI
44

5-
// NB: Deprecated after 0.10.0:
5+
// NB: Deprecated after 0.17.0:
66

77
@available(iOS 13, macOS 10.15, macCatalyst 13, tvOS 13, watchOS 6, *)
8-
extension ActionSheetState {
9-
@available(*, deprecated, message: "'title' and 'message' should be 'TextState'")
10-
@_disfavoredOverload
11-
public init(
12-
title: LocalizedStringKey,
13-
message: LocalizedStringKey? = nil,
14-
buttons: [Button]
15-
) {
16-
self.init(
17-
title: .init(title),
18-
message: message.map { .init($0) },
19-
buttons: buttons
20-
)
21-
}
8+
extension IfLetStore {
9+
@available(*, deprecated, message: "'else' now takes a view builder closure")
10+
public init<IfContent, ElseContent>(
11+
_ store: Store<State?, Action>,
12+
@ViewBuilder then ifContent: @escaping (Store<State, Action>) -> IfContent,
13+
else elseContent: @escaping @autoclosure () -> ElseContent
14+
) where Content == _ConditionalContent<IfContent, ElseContent> {
15+
self.init(store, then: ifContent, else: elseContent)
2216
}
17+
}
18+
19+
// NB: Deprecated after 0.10.0:
2320

2421
@available(iOS 13, macOS 10.15, macCatalyst 13, tvOS 13, watchOS 6, *)
25-
extension AlertState {
26-
@available(*, deprecated, message: "'title' and 'message' should be 'TextState'")
27-
@_disfavoredOverload
28-
public init(
29-
title: LocalizedStringKey,
30-
message: LocalizedStringKey? = nil,
31-
dismissButton: Button? = nil
32-
) {
33-
self.init(
34-
title: .init(title),
35-
message: message.map { .init($0) },
36-
dismissButton: dismissButton
37-
)
38-
}
22+
extension ActionSheetState {
23+
@available(*, deprecated, message: "'title' and 'message' should be 'TextState'")
24+
@_disfavoredOverload
25+
public init(
26+
title: LocalizedStringKey,
27+
message: LocalizedStringKey? = nil,
28+
buttons: [Button]
29+
) {
30+
self.init(
31+
title: .init(title),
32+
message: message.map { .init($0) },
33+
buttons: buttons
34+
)
35+
}
36+
}
3937

40-
@available(*, deprecated, message: "'title' and 'message' should be 'TextState'")
41-
@_disfavoredOverload
42-
public init(
43-
title: LocalizedStringKey,
44-
message: LocalizedStringKey? = nil,
45-
primaryButton: Button,
46-
secondaryButton: Button
47-
) {
48-
self.init(
49-
title: .init(title),
50-
message: message.map { .init($0) },
51-
primaryButton: primaryButton,
52-
secondaryButton: secondaryButton
53-
)
54-
}
38+
@available(iOS 13, macOS 10.15, macCatalyst 13, tvOS 13, watchOS 6, *)
39+
extension AlertState {
40+
@available(*, deprecated, message: "'title' and 'message' should be 'TextState'")
41+
@_disfavoredOverload
42+
public init(
43+
title: LocalizedStringKey,
44+
message: LocalizedStringKey? = nil,
45+
dismissButton: Button? = nil
46+
) {
47+
self.init(
48+
title: .init(title),
49+
message: message.map { .init($0) },
50+
dismissButton: dismissButton
51+
)
5552
}
5653

54+
@available(*, deprecated, message: "'title' and 'message' should be 'TextState'")
55+
@_disfavoredOverload
56+
public init(
57+
title: LocalizedStringKey,
58+
message: LocalizedStringKey? = nil,
59+
primaryButton: Button,
60+
secondaryButton: Button
61+
) {
62+
self.init(
63+
title: .init(title),
64+
message: message.map { .init($0) },
65+
primaryButton: primaryButton,
66+
secondaryButton: secondaryButton
67+
)
68+
}
69+
}
70+
5771
@available(iOS 13, macOS 10.15, macCatalyst 13, tvOS 13, watchOS 6, *)
58-
extension AlertState.Button {
59-
@available(*, deprecated, message: "'label' should be 'TextState'")
60-
@_disfavoredOverload
61-
public static func cancel(
62-
_ label: LocalizedStringKey,
63-
send action: Action? = nil
64-
) -> Self {
65-
Self(action: action, type: .cancel(label: .init(label)))
66-
}
72+
extension AlertState.Button {
73+
@available(*, deprecated, message: "'label' should be 'TextState'")
74+
@_disfavoredOverload
75+
public static func cancel(
76+
_ label: LocalizedStringKey,
77+
send action: Action? = nil
78+
) -> Self {
79+
Self(action: action, type: .cancel(label: .init(label)))
80+
}
6781

68-
@available(*, deprecated, message: "'label' should be 'TextState'")
69-
@_disfavoredOverload
70-
public static func `default`(
71-
_ label: LocalizedStringKey,
72-
send action: Action? = nil
73-
) -> Self {
74-
Self(action: action, type: .default(label: .init(label)))
75-
}
82+
@available(*, deprecated, message: "'label' should be 'TextState'")
83+
@_disfavoredOverload
84+
public static func `default`(
85+
_ label: LocalizedStringKey,
86+
send action: Action? = nil
87+
) -> Self {
88+
Self(action: action, type: .default(label: .init(label)))
89+
}
7690

77-
@available(*, deprecated, message: "'label' should be 'TextState'")
78-
@_disfavoredOverload
79-
public static func destructive(
80-
_ label: LocalizedStringKey,
81-
send action: Action? = nil
82-
) -> Self {
83-
Self(action: action, type: .destructive(label: .init(label)))
84-
}
91+
@available(*, deprecated, message: "'label' should be 'TextState'")
92+
@_disfavoredOverload
93+
public static func destructive(
94+
_ label: LocalizedStringKey,
95+
send action: Action? = nil
96+
) -> Self {
97+
Self(action: action, type: .destructive(label: .init(label)))
8598
}
99+
}
86100
#endif
87101

88102
// NB: Deprecated after 0.9.0:

Sources/ComposableArchitecture/SwiftUI/ForEachStore.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ where Data: Collection, ID: Hashable, Content: View {
7373
public init<EachContent>(
7474
_ store: Store<Data, (Data.Index, EachAction)>,
7575
id: KeyPath<EachState, ID>,
76-
content: @escaping (Store<EachState, EachAction>) -> EachContent
76+
@ViewBuilder content: @escaping (Store<EachState, EachAction>) -> EachContent
7777
)
7878
where
7979
Data == [EachState],
@@ -106,7 +106,7 @@ where Data: Collection, ID: Hashable, Content: View {
106106
/// - content: A function that can generate content given a store of an element.
107107
public init<EachContent>(
108108
_ store: Store<Data, (Data.Index, EachAction)>,
109-
content: @escaping (Store<EachState, EachAction>) -> EachContent
109+
@ViewBuilder content: @escaping (Store<EachState, EachAction>) -> EachContent
110110
)
111111
where
112112
Data == [EachState],
@@ -128,7 +128,7 @@ where Data: Collection, ID: Hashable, Content: View {
128128
/// - content: A function that can generate content given a store of an element.
129129
public init<EachContent: View>(
130130
_ store: Store<IdentifiedArray<ID, EachState>, (ID, EachAction)>,
131-
content: @escaping (Store<EachState, EachAction>) -> EachContent
131+
@ViewBuilder content: @escaping (Store<EachState, EachAction>) -> EachContent
132132
)
133133
where
134134
EachContent: View,

0 commit comments

Comments
 (0)