Hi,
I'm struggling to determine the appropriate way to enable a UI-based application to manage async tasks that may complete in any order.
Suppose I have a list view for which the app wants to asynnchronously fetch an associated image for each currently visible row in the list view.
Traditionally, I might do something like this (ignoring the possibility of errors for brevity):
for let row in /* list of rows for visible list view items */ {
imageService.fetchImage(url: row.imageURL) {
imageData in
// update appropriate list view item 'row' imageData
}
}
Now whatever order each image fetches complete, the respective list item image will be updated.
Supposing I then decide to switch to using structured concurrency, I might imagine that imageService could/should be wrapped as an actor. Say I have this in variable imageServiceActor.
Now, however, it isn't clear how the UI-based code would interact with such an actor such that each image could be displayed once its (async) fetch has completed.
Looking at the option of child tasks (Task.withGroup), it looks like the caller (e.g. of imageServiceActor.fetchSomeImages) would need to have the actor "call back" to the UI thread as each child image fetch completes.
Looking at theoption of detached tasks (Task.runDetached), it looks like the caller (e.g. of imageServiceActor.fetchSomeImages) would need to receive back from the actor an array of task handles or similar?
Which leads to some questions:
(1) What is the likely recommended pattern for migrating UI-based code that currently benefits from "any-order" completion of async network requests, to using actors?
(2) If child tasks are proposed: how can/should an actor "call back" the UI thread in this kind of situation?
(3) If detached tasks are proposed: how can a caller that receives an array of task handles "poll" the handles similar to a task group's 'next' function?
I appreciate that structured concurrency is intended to allow for async patterns for a variety of environments (including servers on many-core systems), and we may hope that in future, ARC overheads can be avoided/reduced significantly in actor-based systems so that Swift will be more compelling for building server applications.
However a huge number of Swift apps are UI-based client applications, and updating the pitches/proposals to explicitly cover expected/recommended patterns for actor usage with UI-based apps (that currently benefit from "out of order" completion of async requests), seems to me to be extremely important.