I'm new to Swift, coming from JS, and I've started to build an iOS app.
Initially I went down the road, using Promise Kit for the async stuff, as it seemed easier to me than other things I read about.
Regardless, in JS, I use the following pattern a lot:
async function doAyncFunction(item) {
try {
// do async call to fetch data using item
return Promise.resolve(data);
} catch (error) {
return Promise.reject(error);
}
}
const promises = items.map((item) => doAyncFunction(item));
const results = await Promise.all(promises);
And I ultimately got this working with Promise Kit with something like this:
func doManyAsyncRequests(userIds: [String], accessToken: String) -> Promise<Void> {
Promise { seal in
let promises = spotifyUserIds.map {
doSingleAsyncRequest(userId: $0.id, accessToken: accessToken) // this function returns a promise
}
when(fulfilled: promises).done { results in
print("Results: \(results)")
// process results
}.catch { error in
print("\(error)")
// handle error
}
}
}
Promise Kit's when
is similar to JavaScript's Promise.all()
in that once the promises are fulfilled, things are triggered to move along in the code.
As my learning curve is slow enough, I've decided to start coding for iOS 15 and use Swift async/await.
QUESTION: What Swift async/await pattern that will do the above, similar to Promise Kit's wait
and JavaScript's Promise.all()
?
Thanks.
UPDATE: Thanks to @workingdog, who helped me arrive at the solution below. I now gotta work on error handling, but that's a different topic for now.
func getAllThings(users: [User], accessToken: String) async -> [Thing] {
var allThings: [Thing] = []
await withTaskGroup(of: [Thing].self) { group in
for user in users {
group.async {
let userThings = await self.getUsersThings(
accessToken: accessToken,
displayName: user.displayName,
userId: user.id
)
return userThings
}
}
for await (userThings) in group {
allThings = allThings + userThings
}
}
return allThings
}