[Post-review Update] SF-0023 ProgressManager

Hello all,

The author of SF-0023 ProgressManager: Progress Reporting in Swift Concurrency, Chloe, wants to propose a minor post-review update for SF-0023. Reviews for these updates begin now and run through Monday, October 6th, 2025.

Pitch Thread

First Review

Second Pitch Thread

Second Review

Here's a summary of changes:

  • Replaced withProperties method with setCounts

  • Removed ProgressManager.Values struct

  • Made ProgressManager conform to @dynamicMemberLookup and moved subscript(dynamicMember:) methods from ProgressManager.Values to ProgressManager

  • Changed behavior of API so that additional properties are restricted to either Int, Double, String?, URL?, UInt64 or Duration types instead of any Sendable types

  • Added overloads for subscript(dynamicMember:) to account for currently-allowed types

  • Added requirements to ProgressManager.Property protocol to define summarization and termination (deinit) behavior

  • Replaced total(of:) with overloads for summary(of:) to account for all available types and removed values(of:) method

Reviews are an important part of the Swift-Foundation evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to me as the review manager by email or DM. When contacting the review manager directly, please include proposal name in the subject line.

Trying it out

Checkout the implementation PR here

More information about Swift-Foundation review process is available at

swift-foundation/CONTRIBUTING.md at main · swiftlang/swift-foundation · GitHub

Thank you,

Charles Hu

Review Manager

2 Likes

Is this scheduled for release in Swift 6.3?

1 Like

As seen in the source file this is merged with availability of 6.4

1 Like

Resurrecting this thread to note, since Xcode 27 beta has shipped with ProgressManager enabled, that #83359 is still not fixed, so all concurrent observation does not work correctly, which means that using ProgressManager to monitor concurrent work is unreliable.

Here's a ContentView to paste into a new iOS project that demonstrates the problem:

struct ContentView: View {

    @State var manager = ProgressManager(totalCount: 10)
    @State var id = 0

    var body: some View {
        VStack {
            Button("Count to 10") {
                id += 1
            }
            ProgressView(
                value: manager.fractionCompleted,
                total: 1.0
            )
            Text("\(manager.completedCount)/\(manager.totalCount!)")
        }
            .padding()
            .task(id: id) {
                manager = ProgressManager(totalCount: 10)
                await Task.detached { [manager] in
                    for _ in 0..<10 {
                        manager.complete(count: 1)
                    }
                }.value
            }
    }
}

Most presses of "count to ten" will result in the progress bar being set to 10/10, but some will not. 0/10 is the most common "other value" to stop at, but you can see everything in between if you click the button enough times.

2 Likes

Thanks for the report. I filed an issue on your behalf: ProgressManager: concurrent observation does not work correctly · Issue #2053 · swiftlang/swift-foundation · GitHub

Thanks. Although it certainly doesn't work as expected, I don't believe that ProgressManager itself needs to be fixed, only withObservationTracking and friends. And I don't believe this problem can be fixed at the Foundation level.

Yup I agree. I created one in swift-foundation for @chloe-yeo's convenience since she has been working with @Philippe_Hausler on verifying the observation fix; not that I think it's a bug in swift-foundation per-se

1 Like