Strict concurrency warnings and UIApplication beginBackgroundTask

I'm experimenting with using strict concurrency checking and one challenge I've run into is that UIApplication is marked as MainActor. Starting background tasks from a non-main context seems like something that should be safe? Am I missing something here or is UIApplication truly not thread safe / need to be strictly accessed from main?

I don't know the reasons but it's long been true that UIApplication (and much of UIKit) should only be accessed from main. Even before Swift concurrency there were runtime issues and external linter warnings about that.

1 Like

Even for stuff like background tasks? Obviously things like UIView are MainActor, but there are exceptions like UIImage.

Yes, all UIApplication interactions, even those that give you executable contexts not on the main actor. it just means you have to access UIApplication.shared on the main actor, not that the work in the background task has to as well.

The background task subsystem within UIApplication is thread safe [1], but it’s hard for Swift concurrency to express that.

Still, my experience is that it’s best to begin and end background tasks on the main thread because your expiry handler is called on the main thread. If you begin and end background tasks on a secondary thread, it’s hard to coordinate that work with the expiry handler.

For more hints and tips, see UIApplication Background Task Notes on DevForums.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

[1] We even call that out in the docs.


Isn't it merely a matter of putting the @MainActor markers on individual methods instead of on the class itself?

1 Like

How would you decorate UIApplication.shared?

How would you handle UIApplication subclasses?

Honestly, I don’t have all the answers here, which is kinda why I used that mealy-mouthed phrasing (-:

If I had Engineering Credits™ to use on this problem, I wouldn’t spend them to try to fix the concurrency annotations for UIApplication background tasks. Rather, I’d spend them on making the equivalent ProcessInfo API more usable. That would:

  • Be easier to do — Because it’s new API, not tied to UIApplication.

  • Help more folks — Remember that an appex can’t access UIApplication.

Sadly, I’m all out of Engineering Credits™, so all I can do is file a bug (r. 109839489).

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like