Skip to content

Conversation

@alexandre-pod
Copy link

Swift 6.2 added a new API to create a task: Task.immediate(name:priority:executorpreference:operation:), also described in SE-0472 Starting tasks synchronously from caller context.

Using this new api makes possible to remove the delay between the user gesture and the execution of the action, at least until an asynchronous operation is awaited.

Here what can be observed with this change on the demo project. With Task.immediate we prevent the loader to being shown as the reset button executes its action immediately.

Using.Task.immediate.creation.mov
Using.Task.creation.mov

Note: As this new API is only available on 26.0 version of various of operating systems, the old behaviour is kept when this API is not available.

@Dean151 Dean151 self-assigned this Nov 12, 2025
@Dean151 Dean151 added the enhancement New feature or request label Nov 12, 2025
@Dean151
Copy link
Owner

Dean151 commented Nov 27, 2025

Does it build against older Swift versions?
If I am to build this with 6.1, will I encounter a build error as it's a language feature as well?

@alexandre-pod
Copy link
Author

Does it build against older Swift versions? If I am to build this with 6.1, will I encounter a build error as it's a language feature as well?

I haven't thought about that, and you are right when using a Swift version below 6.2 it fails to compile with the error: Type 'Task<Success, Failure>' has no member 'immediate'.
I have pushed a fix that only use the new Task.immediate API when building with 6.2.

@alexandre-pod
Copy link
Author

With the latest commit I was able to build and run the demo app using Xcode 16.2.0 that is using Swift 6.0.

@Dean151
Copy link
Owner

Dean151 commented Jan 26, 2026

It also builds on Swift 5.10 (tested just now).
Sorry it took me so long to test that, but 5.10 build was broken on main branch, and it took me way too much time to get back to it.

@Dean151
Copy link
Owner

Dean151 commented Jan 26, 2026

I've been reviewing the code, and I might find a potential issue.
When immediate task ends immediately, state is never set to "started", and move either from:
nil -> .ended (first press of the button)
.ended(previous) -> .ended(current) (subsequent presses of the button)

This makes few features of the library related to button events unreliable:

  • onStateChange / asyncButtonTaskChanged is called only once instead of twice for current loading behavior
  • asyncButtonTaskStarted will never be called

Sadly this could break current lib users behavior.
Therefore I also can see that my current implementation might have a problem where I could be setting the ended before even setting the started. This is because the task stored in the started contains the "ended" setter, which makes it impossible to settle right, I think.

I need to think this more through.

@Dean151
Copy link
Owner

Dean151 commented Jan 27, 2026

This could be a solution, but I'm not sure for my 1AM reasoning.
Can you double check?
a78ded0

@alexandre-pod
Copy link
Author

This could be a solution, but I'm not sure for my 1AM reasoning. Can you double check? a78ded0

You're right, this Task.immediate seems to break the apis around the onStateChange init argument and the ButtonLatestStatePreferenceKey.self preference value. This is because the Task.immediate will start and finish without interruption nor delay.
Your fix seems promising but it does not really works due to how SwiftUI works:
The state property of Button will always be set to .starting / .ended with your fix. And it does so without delay when possible thanks to the use of Task.immediate. But when the state is set to .started SwiftUI will not call the body until later, which will be after the state = .ended(...) (in the case the action was synchronous).
The .onChange(of: state) and .preference(key: ButtonLatestStatePreferenceKey.self, ... will never have the chance to observe the start state, so the current lib behaviour is still broken...

I am not seeing right now a simple solution to keep the existing behavior, while using Task.immediate and its reduced start time 😢

@Dean151 Dean151 added the help wanted Extra attention is needed label Jan 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request help wanted Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants