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.
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?
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