Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8a03e6a
wip
stephencelis Sep 13, 2024
3fe6fb0
wip
stephencelis Sep 13, 2024
9122a3a
wip
stephencelis Sep 13, 2024
f80cb3b
wip
stephencelis Sep 13, 2024
f67562a
wip
stephencelis Sep 13, 2024
2bd4f44
wip
stephencelis Sep 13, 2024
00ad75e
wip
stephencelis Sep 13, 2024
65c42e1
wip
stephencelis Sep 13, 2024
e79668e
wip
stephencelis Sep 13, 2024
0665585
wip
stephencelis Sep 13, 2024
a5e7734
wip
stephencelis Sep 13, 2024
0d630e2
wip
stephencelis Sep 13, 2024
edbf4e6
wip
stephencelis Sep 13, 2024
0ae2e54
Merge remote-tracking branch 'origin/main' into core
stephencelis Sep 13, 2024
26e41f9
wip
stephencelis Sep 13, 2024
f4da4c6
wip
stephencelis Sep 13, 2024
33cc53e
wip
stephencelis Sep 13, 2024
052841e
wip
stephencelis Sep 13, 2024
e34e628
wip
stephencelis Sep 13, 2024
712fa8d
wip
stephencelis Sep 14, 2024
d9eb1f6
wip
stephencelis Sep 14, 2024
603d725
Merge remote-tracking branch 'origin/main' into core
stephencelis Sep 19, 2024
62a61c3
get rid of originating action
mbrandonw Sep 27, 2024
c70426f
wip
stephencelis Oct 2, 2024
bef3861
Merge remote-tracking branch 'origin/main' into core
stephencelis Oct 8, 2024
e58cba5
Merge remote-tracking branch 'origin/main' into core
stephencelis Oct 16, 2024
c3338b5
Merge remote-tracking branch 'origin/main' into core
stephencelis Oct 21, 2024
413c24c
Merge branch 'main' into core
stephencelis Nov 12, 2024
bbe33b7
Merge remote-tracking branch 'origin/main' into core
stephencelis Feb 6, 2025
47d606b
Merge remote-tracking branch 'origin/main' into core
stephencelis Feb 27, 2025
58fddea
Merge remote-tracking branch 'origin/main' into core
stephencelis Feb 27, 2025
1b7f72c
wip
stephencelis Feb 28, 2025
5714403
Merge remote-tracking branch 'origin/main' into core
stephencelis Mar 13, 2025
95570eb
Deprecate non-writable scopes
stephencelis Mar 13, 2025
31b0755
Revert "Deprecate non-writable scopes"
stephencelis Mar 13, 2025
f05ac83
Merge branch 'main' into core
stephencelis Mar 26, 2025
725189d
wip
stephencelis Mar 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge remote-tracking branch 'origin/main' into core
  • Loading branch information
stephencelis committed Feb 27, 2025
commit 58fddea67467ac28ef64dc8e4d8906a1ab09a2d9
20 changes: 10 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
matrix:
command: [test, '']
platform: [IOS, MACOS]
xcode: ['16.0']
xcode: ['16.2']
steps:
- uses: actions/checkout@v4
- name: Select Xcode ${{ matrix.xcode }}
Expand Down Expand Up @@ -117,27 +117,27 @@ jobs:
restore-keys: |
deriveddata-examples-
- name: Select Xcode 16
run: sudo xcode-select -s /Applications/Xcode_16.0.app
run: sudo xcode-select -s /Applications/Xcode_16.2.app
- name: Set IgnoreFileSystemDeviceInodeChanges flag
run: defaults write com.apple.dt.XCBuild IgnoreFileSystemDeviceInodeChanges -bool YES
- name: Update mtime for incremental builds
uses: chetan/git-restore-mtime-action@v2
- name: CaseStudies (SwiftUI)
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="CaseStudies (SwiftUI)" xcodebuild-raw
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="CaseStudies (SwiftUI)" xcodebuild
- name: CaseStudies (UIKit)
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="CaseStudies (UIKit)" xcodebuild-raw
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="CaseStudies (UIKit)" xcodebuild
- name: Search
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="Search" xcodebuild-raw
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="Search" xcodebuild
- name: SyncUps
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="SyncUps" xcodebuild-raw
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="SyncUps" xcodebuild
- name: SpeechRecognition
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="SpeechRecognition" xcodebuild-raw
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="SpeechRecognition" xcodebuild
- name: TicTacToe
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="TicTacToe" xcodebuild-raw
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="TicTacToe" xcodebuild
- name: Todos
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="Todos" xcodebuild-raw
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="Todos" xcodebuild
- name: VoiceMemos
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="VoiceMemos" xcodebuild-raw
run: make DERIVED_DATA_PATH=~/.derivedData SCHEME="VoiceMemos" xcodebuild

check-macro-compatibility:
name: Check Macro Compatibility
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ jobs:

for tag in $(echo "main"; git tag -l --sort=-v:refname | grep -e "\d\+\.\d\+.0" | head -6);
do
if [ -d "docs-out/$tag/data/documentation/composablearchitecture" ]
then
if [ -d "docs-out/$tag/data/documentation/composablearchitecture" ]
then
echo "✅ Documentation for "$tag" already exists.";
else
else
echo "⏳ Generating documentation for ComposableArchitecture @ "$tag" release.";
rm -rf "docs-out/$tag";

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 5 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ CONFIG = Debug

DERIVED_DATA_PATH = ~/.derivedData/$(CONFIG)

PLATFORM_IOS = iOS Simulator,id=$(call udid_for,iOS,iPhone \d\+ Pro [^M])
PLATFORM_IOS = iOS Simulator,id=$(call udid_for,iPhone)
PLATFORM_MACOS = macOS
PLATFORM_MAC_CATALYST = macOS,variant=Mac Catalyst
PLATFORM_TVOS = tvOS Simulator,id=$(call udid_for,tvOS,TV)
PLATFORM_VISIONOS = visionOS Simulator,id=$(call udid_for,visionOS,Vision)
PLATFORM_WATCHOS = watchOS Simulator,id=$(call udid_for,watchOS,Watch)
PLATFORM_TVOS = tvOS Simulator,id=$(call udid_for,TV)
PLATFORM_VISIONOS = visionOS Simulator,id=$(call udid_for,Vision)
PLATFORM_WATCHOS = watchOS Simulator,id=$(call udid_for,Watch)

PLATFORM = IOS
DESTINATION = platform="$(PLATFORM_$(PLATFORM))"
Expand Down Expand Up @@ -47,7 +47,6 @@ warm-simulator:
xcodebuild: warm-simulator
$(XCODEBUILD)

# Workaround for debugging Swift Testing tests: https://github.com/cpisciotta/xcbeautify/issues/313
xcodebuild-raw: warm-simulator
$(XCODEBUILD_COMMAND)

Expand All @@ -69,5 +68,5 @@ format:
.PHONY: build-for-library-evolution format warm-simulator xcodebuild xcodebuild-raw

define udid_for
$(shell xcrun simctl list devices available '$(1)' | grep '$(2)' | sort -r | head -1 | awk -F '[()]' '{ print $$(NF-3) }')
$(shell xcrun simctl list --json devices available '$(1)' | jq -r '[.devices|to_entries|sort_by(.key)|reverse|.[].value|select(length > 0)|.[0]][0].udid')
endef
6 changes: 3 additions & 3 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions Sources/ComposableArchitecture/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ final class RootCore<Root: Reducer>: Core {
defer { index += 1 }
let action = self.bufferedActions[index]
let effect = reducer.reduce(into: &currentState, action: action)
let uuid = UUID()

switch effect.operation {
case .none:
break
case let .publisher(publisher):
var didComplete = false
let boxedTask = Box<Task<Void, Never>?>(wrappedValue: nil)
let uuid = UUID()
let effectCancellable = withEscapedDependencies { continuation in
publisher
.receive(on: UIScheduler.shared)
Expand Down Expand Up @@ -128,11 +128,13 @@ final class RootCore<Root: Reducer>: Core {
}
boxedTask.wrappedValue = task
tasks.withValue { $0.append(task) }
self.effectCancellables[uuid] = effectCancellable
self.effectCancellables[uuid] = AnyCancellable {
task.cancel()
}
}
case let .run(priority, operation):
withEscapedDependencies { continuation in
let task = Task(priority: priority) { @MainActor in
let task = Task(priority: priority) { @MainActor [weak self] in
let isCompleted = LockIsolated(false)
defer { isCompleted.setValue(true) }
await operation(
Expand All @@ -158,14 +160,18 @@ final class RootCore<Root: Reducer>: Core {
)
}
if let task = continuation.yield({
self.send(effectAction)
self?.send(effectAction)
}) {
tasks.withValue { $0.append(task) }
}
}
)
self?.effectCancellables[uuid] = nil
}
tasks.withValue { $0.append(task) }
self.effectCancellables[uuid] = AnyCancellable {
task.cancel()
}
}
}
}
Expand Down
41 changes: 35 additions & 6 deletions Tests/ComposableArchitectureTests/StoreLifetimeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@_spi(Logging) import ComposableArchitecture
import XCTest

@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
final class StoreLifetimeTests: BaseTCATestCase {
@available(*, deprecated)
@MainActor
Expand Down Expand Up @@ -69,9 +70,6 @@

@MainActor
func testStoreDeinit_RunningEffect() async {
XCTTODO(
"We would like for this to pass, but it requires full deprecation of uncached child stores"
)
Logger.shared.isEnabled = true
let effectFinished = self.expectation(description: "Effect finished")
do {
Expand Down Expand Up @@ -99,9 +97,6 @@

@MainActor
func testStoreDeinit_RunningCombineEffect() async {
XCTTODO(
"We would like for this to pass, but it requires full deprecation of uncached child stores"
)
Logger.shared.isEnabled = true
let effectFinished = self.expectation(description: "Effect finished")
do {
Expand Down Expand Up @@ -129,28 +124,61 @@
await self.fulfillment(of: [effectFinished], timeout: 0.5)
}
#endif

@MainActor
@available(*, deprecated)
func testUnCachedStores() async {
Logger.shared.isEnabled = true
let clock = TestClock()
let store = Store(initialState: Parent.State()) {
Parent()
} withDependencies: {
$0.continuousClock = clock
}
do {
let child = store.scope(state: { $0.child }, action: { .child($0) })
child.send(.start)
XCTAssertEqual(store.withState(\.child.count), 1)
}
await clock.run()

Check failure on line 143 in Tests/ComposableArchitectureTests/StoreLifetimeTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (16) (test, IOS, 16.2)

testUnCachedStores, failed - Expected all sleeps to finish, but some are still suspending after 0.5 seconds.

Check failure on line 143 in Tests/ComposableArchitectureTests/StoreLifetimeTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

testUnCachedStores, failed - Expected all sleeps to finish, but some are still suspending after 0.5 seconds.
XCTAssertEqual(store.withState(\.child.count), 2)

Check failure on line 144 in Tests/ComposableArchitectureTests/StoreLifetimeTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (16) (test, IOS, 16.2)

testUnCachedStores, XCTAssertEqual failed: ("1") is not equal to ("2")
}
}

@Reducer
@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
private struct Child {
struct State: Equatable {
var count = 0
}
enum Action {
case tap
case start
case response
}
@Dependency(\.continuousClock) var clock
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .tap:
state.count += 1
return .none
case .start:
state.count += 1
return .run { send in
try await clock.sleep(for: .seconds(0))
await send(.response)
}
case .response:
state.count += 1
return .none
}
}
}
}

@Reducer
@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
private struct Parent {
struct State: Equatable {
var child = Child.State()
Expand All @@ -166,6 +194,7 @@
}

@Reducer
@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
private struct Grandparent {
struct State: Equatable {
var child = Parent.State()
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.