diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4bcfaed6612..85ac134f90e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,19 +21,19 @@ jobs: matrix: command: [test, ''] platform: [iOS, macOS, tvOS, watchOS, visionOS, macCatalyst] - xcode: [15.2, 15.4, 16_beta_6] - exclude: + xcode: [15.2, 15.4, '16.0'] + exclude: - {xcode: 15.2, command: test} - {xcode: 15.4, command: ''} - {xcode: 15.2, platform: macCatalyst} - {xcode: 15.2, platform: tvOS} - {xcode: 15.2, platform: visionOS} - {xcode: 15.2, platform: watchOS} - - {xcode: 16_beta_6, command: ''} - - {xcode: 16_beta_6, platform: macCatalyst} - - {xcode: 16_beta_6, platform: tvOS} - - {xcode: 16_beta_6, platform: visionOS} - - {xcode: 16_beta_6, platform: watchOS} + - {xcode: '16.0', command: ''} + - {xcode: '16.0', platform: macCatalyst} + - {xcode: '16.0', platform: tvOS} + - {xcode: '16.0', platform: visionOS} + - {xcode: '16.0', platform: watchOS} include: - {xcode: 15.2, skip_release: 1} steps: @@ -83,7 +83,7 @@ jobs: restore-keys: | deriveddata-examples- - name: Select Xcode 16 - run: sudo xcode-select -s /Applications/Xcode_16_beta_6.app + run: sudo xcode-select -s /Applications/Xcode_16.0.app - name: Set IgnoreFileSystemDeviceInodeChanges flag run: defaults write com.apple.dt.XCBuild IgnoreFileSystemDeviceInodeChanges -bool YES - name: Update mtime for incremental builds diff --git a/Sources/ComposableArchitecture/Documentation.docc/Articles/MigrationGuides/MigratingTo1.7.md b/Sources/ComposableArchitecture/Documentation.docc/Articles/MigrationGuides/MigratingTo1.7.md index b50a877f7633..bfbe8fd03c2a 100644 --- a/Sources/ComposableArchitecture/Documentation.docc/Articles/MigrationGuides/MigratingTo1.7.md +++ b/Sources/ComposableArchitecture/Documentation.docc/Articles/MigrationGuides/MigratingTo1.7.md @@ -889,6 +889,8 @@ rather than going through ``Store/send(_:)``: ## Observing for UIKit +### Replacing Store.publisher + Prior to the observation tools one would typically subscribe to changes in the store via a Combine publisher in the entry point of a view, such as `viewDidLoad` in a `UIViewController` subclass: @@ -921,6 +923,35 @@ func viewDidLoad() { Be sure to read the documentation for ``ObjectiveC/NSObject/observe(_:)`` to learn how to best wield this tool. +### Replacing Store.ifLet + +Prior to the observation tools one would typically subscribe to optional child stores via a Combine +operation provided by the library: + +```swift +store + .scope(state: \.child, action: \.child) + .ifLet { childStore in + // Use child store, _e.g._ create a child view controller + } else: { + // Perform clean up work, _e.g._ dismiss child view controller + } + .store(in: &cancellables) +``` + +This can now be done more simply using the `observe` method and +``Store/scope(state:action:fileID:filePath:line:column:)-2ck1n``: + +```swift +observe { + if let childStore = store.scope(state: \.child, action: \.child) { + // Use child store, _e.g._ create a child view controller + } else { + // Perform clean up work, _e.g._ dismiss child view controller + } +} +``` + ## Incrementally migrating You are most likely going to want to incrementally migrate your application to the new observation tools, diff --git a/Sources/ComposableArchitecture/Documentation.docc/Extensions/Deprecations/StoreDeprecations.md b/Sources/ComposableArchitecture/Documentation.docc/Extensions/Deprecations/StoreDeprecations.md index dcb28f736691..6efdb36c8489 100644 --- a/Sources/ComposableArchitecture/Documentation.docc/Extensions/Deprecations/StoreDeprecations.md +++ b/Sources/ComposableArchitecture/Documentation.docc/Extensions/Deprecations/StoreDeprecations.md @@ -12,3 +12,7 @@ instead. ### Scoping stores - ``Store/scope(state:action:)-9iai9`` + +### UIKit integration + +- ``ifLet(then:else:)`` diff --git a/Sources/ComposableArchitecture/Documentation.docc/Extensions/Store.md b/Sources/ComposableArchitecture/Documentation.docc/Extensions/Store.md index 37b5d377e3e6..bc16c4fe1364 100644 --- a/Sources/ComposableArchitecture/Documentation.docc/Extensions/Store.md +++ b/Sources/ComposableArchitecture/Documentation.docc/Extensions/Store.md @@ -35,10 +35,6 @@ - ``StorePublisher`` -### UIKit integration - -- ``ifLet(then:else:)`` - ### Deprecated interfaces - diff --git a/Sources/ComposableArchitecture/UIKit/IfLetUIKit.swift b/Sources/ComposableArchitecture/UIKit/IfLetUIKit.swift index 93dda83a0cbb..57b9d7adf1f1 100644 --- a/Sources/ComposableArchitecture/UIKit/IfLetUIKit.swift +++ b/Sources/ComposableArchitecture/UIKit/IfLetUIKit.swift @@ -45,6 +45,10 @@ extension Store { /// goes from non-`nil` to `nil`. /// - Returns: A cancellable that maintains a subscription to updates whenever the store's state /// goes from `nil` to non-`nil` and vice versa, so that the caller can react to these changes. + @available(iOS, deprecated: 9999, message: "Use 'observe' and 'if let store.scope', instead.") + @available(macOS, deprecated: 9999, message: "Use 'observe' and 'if let store.scope', instead.") + @available(tvOS, deprecated: 9999, message: "Use 'observe' and 'if let store.scope', instead.") + @available(watchOS, deprecated: 9999, message: "Use 'observe' and 'if let store.scope', instead.") public func ifLet( then unwrap: @escaping (_ store: Store) -> Void, else: @escaping () -> Void = {}