Meet Swift Async Algorithms

RSS for tag

Discuss the WWDC22 Session Meet Swift Async Algorithms

Posts under wwdc2022-110355 tag

1 result found
Sort by:
Post not yet marked as solved
1 Replies
1.2k Views
Hey there, I have a problem running multiply tasks in parallel in a SwiftUI view. struct ModelsView: View { @StateObject var tasks = TasksViewModel() var body: some View { NavigationView{ ScrollView { ForEach(Array(zip(tasks.tasks.indices, tasks.tasks)), id: \.0) { task in NavigationLink(destination: ModelView()) { ModelPreviewView(model_name: "3dobject.usdz") .onAppear { if task.0 == tasks.tasks.count - 2 { Task { print(tasks.tasks.count) await tasks.fetch_tasks(count: 4) } } } } } }.navigationTitle("3D modelle") }.onAppear{ Task { await tasks.fetch_tasks(count: 5) await tasks.watch_for_new_tasks() } } } } In my view, I spawn a task as soon as the View Appears which, first, fetches 5 tasks from the database (this works fine), and then it starts watching for new tasks. In the Scroll View, right before the bottom is reached, I start loading new tasks. The problem is, the asynchronous function fetch_tasks(count: 4) only gets continued if the asynchronous function watch_for_new_tasks() stops blocking. actor TasksViewModel: ObservableObject { @MainActor @Published private(set) var tasks : [Tasks.Task] = [] private var last_fetched_id : String? = nil func fetch_tasks(count: UInt32) async { do { let tasks_data = try await RedisClient.shared.xrevrange(streamName: "tasks", end: last_fetched_id ?? "+" , start: "-", count: count) last_fetched_id = tasks_data.last?.id let fetched_tasks = tasks_data.compactMap { Tasks.Task(from: $0.data) } await MainActor.run { withAnimation(.easeInOut) { self.tasks.append(contentsOf: fetched_tasks) } } } catch { print("Error fetching taskss \(error)") } } func watch_for_new_tasks() async { while !Task.isCancelled { do { let tasks_data = try await RedisClient.shared.xread(streams: "tasks", ids: "$") let new_tasks = tasks_data.compactMap { Tasks.Task(from: $0.data) } await MainActor.run { for new_task in new_tasks.reversed() { withAnimation { self.tasks.insert(new_task, at: 0) } } } } catch { print(error) } } } ... } The asynchronous function watch_for_new_tasks() uses RedisClient.shared.xread(streams: "tasks", ids: "$") which blocks until at least one tasks is added to the Redis Stream. I tried running the watch_for_new_tasks() on a Task.detached tasks, but that also blocks. To be honest, I have no idea why this blocks, and I could use your guy's help if you could. Thank you in Advance, Michael
Posted
by Wikipedia.
Last updated
.