mirror of
https://github.com/pointfreeco/swift-composable-architecture.git
synced 2025-12-24 12:14:25 +01:00
Swift 6 updates (#3379)
* Swift 6 updates
- Soft-deprecate `_SynthesizedConformance` now that Xcode 16 has fixed
this bug.
- Update docs accordingly.
- Document Xcode 16 macro gotcha around custom build configuration
names.
* wip
This commit is contained in:
@@ -3,11 +3,12 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
}
|
||||
// ...
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
struct SyncUpDetailView: View {
|
||||
// ...
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -14,6 +14,7 @@ struct SyncUpDetail {
|
||||
}
|
||||
// ...
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
struct SyncUpDetailView: View {
|
||||
// ...
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -78,6 +78,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$alert, action: \.alert)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -79,6 +79,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$alert, action: \.alert)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -77,6 +77,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$alert, action: \.alert)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -73,6 +73,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$destination, action: \.destination)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -70,6 +70,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$destination, action: \.destination)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -67,6 +67,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$destination, action: \.destination)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -67,6 +67,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$destination, action: \.destination)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -65,6 +65,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$destination, action: \.destination)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -64,6 +64,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$destination, action: \.destination)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -65,6 +65,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$destination, action: \.destination)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Action.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct SyncUpDetail {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case alert(AlertState<Alert>)
|
||||
case edit(SyncUpForm)
|
||||
@@ -65,6 +65,7 @@ struct SyncUpDetail {
|
||||
.ifLet(\.$destination, action: \.destination)
|
||||
}
|
||||
}
|
||||
extension SyncUpDetail.Destination.State: Equatable {}
|
||||
|
||||
extension AlertState where Action == SyncUpDetail.Destination.Alert {
|
||||
static let deleteSyncUp = Self {
|
||||
|
||||
@@ -368,10 +368,7 @@
|
||||
|
||||
> Important: As we have seen it is important for `State` types to be `Equatable` for
|
||||
testing, and so we are proactively making the `State` type generated for the `Destination`
|
||||
reducer equatable via the `state` argument of
|
||||
``ComposableArchitecture/Reducer(state:action:)``. See the article
|
||||
<doc:Reducer#Circular-reference-errors> for more information of why this is the necessary
|
||||
way to make `State` equatable.
|
||||
reducer equatable _via_ extension.
|
||||
|
||||
> Note: We have collapsed the implementation of `SyncUpDetail` and `SyncUpDetailView` in
|
||||
> this code snippet.
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct AppFeature {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Path {
|
||||
case detail(SyncUpDetail)
|
||||
}
|
||||
@@ -27,3 +27,4 @@ struct AppFeature {
|
||||
}
|
||||
}
|
||||
}
|
||||
extension AppFeature.Path.State: Equatable {}
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct AppFeature {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Path {
|
||||
case detail(SyncUpDetail)
|
||||
}
|
||||
@@ -30,3 +30,4 @@ struct AppFeature {
|
||||
}
|
||||
}
|
||||
}
|
||||
extension AppFeature.Path.State: Equatable {}
|
||||
|
||||
@@ -3,7 +3,7 @@ import SwiftUI
|
||||
|
||||
@Reducer
|
||||
struct AppFeature {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Path {
|
||||
case detail(SyncUpDetail)
|
||||
}
|
||||
@@ -31,3 +31,4 @@ struct AppFeature {
|
||||
.forEach(\.path, action: \.path)
|
||||
}
|
||||
}
|
||||
extension AppFeature.Path.State: Equatable {}
|
||||
|
||||
@@ -92,11 +92,8 @@
|
||||
Update the `path` variable to hold onto ``ComposableArchitecture/StackState`` of
|
||||
`Path.State`.
|
||||
|
||||
> Important: In order to maintain `State`'s `Equatable`, we must conform `Path` to be
|
||||
> `Equatable` as well. While this would typically be done with an extension, a Swift
|
||||
> compiler bug prevents this, so the ``ComposableArchitecture/Reducer(state:action:)`` macro
|
||||
> can generate this conformance for you by specifying the `state` parameter. See the article
|
||||
> <doc:Reducer#Circular-reference-errors> for more.
|
||||
> Important: In order to maintain `State`'s `Equatable`, we must conform `Path.State` to be
|
||||
> `Equatable` as well.
|
||||
|
||||
@Code(name: "App.swift", file: SyncUpDetailNavigation-01-code-0006.swift)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
extension ContactsFeature {
|
||||
@Reducer(state: .equatable)
|
||||
@Reducer
|
||||
enum Destination {
|
||||
case addContact(AddContactFeature)
|
||||
case alert(AlertState<ContactsFeature.Action.Alert>)
|
||||
}
|
||||
}
|
||||
extension ContactsFeature.Destination.State: Equatable {}
|
||||
|
||||
@@ -160,13 +160,8 @@
|
||||
is no longer `Equatable`. This is happening because `Destination.State` is not `Equatable`,
|
||||
and that type is generated by the [`@Reducer`](<doc:ComposableArchitecture/Reducer()>) macro.
|
||||
|
||||
Due to a bug in the Swift compiler it is not possible to extend `Destination.State` to be
|
||||
`Equatable` yourself, and so there is an argument you can provide
|
||||
``ComposableArchitecture/Reducer()`` in order to apply the protocol conformance.
|
||||
|
||||
@Step {
|
||||
Use the `state` argument of ``ComposableArchitecture/Reducer(state:action:)`` to tell the
|
||||
macro to apply an `Equatable` conformance to `Destination.State`.
|
||||
Extend the macro-generated `Destination.State` to apply an `Equatable` conformance.
|
||||
|
||||
@Code(name: "ContactsFeatures.swift", file: 02-02-02-code-0004.swift, previousFile: 02-02-02-code-0004-previous.swift)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user