Swift:iOS 15 之前的任务 {}?

Ano*_*ude 5 task swift swiftui

我正在按照教程来了解 SwiftUI,特别是如何在视图出现时调用 API。

我看到了这个:

List(results, id: \.trackId) { item in
    ListRow(item)
}
.task {
    // perform API here
}
Run Code Online (Sandbox Code Playgroud)

但由于我的应用程序面向 iOS 14,我收到此错误:

“task(priority:_:)”仅在 iOS 15.0 或更高版本中可用

那么我能做什么呢?感谢您的帮助

小智 9

您可以编写适用于 iOS 13、iOS 14 的版本task { },并使用适用于 iOS 15 的苹果版本:

extension View {
    @available(iOS, deprecated: 15.0, message: "This extension is no longer necessary. Use API built into SDK")
    func task(priority: TaskPriority = .userInitiated, _ action: @escaping @Sendable () async -> Void) -> some View {
        self.onAppear {
            Task(priority: priority) {
                await action()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


ale*_*omp 6

仅仅切换到是不正确的,因为它缺少结构化并发.onAppear的要点。每次你创造一个自己时,你都应该怀疑,你正在做一些不寻常的事情。Task

当然,在这种情况下,我们没有可用的“结构化并发感知”生命周期修饰符,因此我们需要使用Taskinit 创建自己的生命周期修饰符,但这意味着您需要负责尊重结构化并发!

这意味着要获得适当的向后兼容解决方案,需要编写更多代码,因为您希望正确处理取消。为此,您还需要使用.onDisappear并取消您开始的任务.onAppear

如果您想让它可重用,您可以创建自定义 .task 修饰符


lor*_*sum 5

async await适用于 iOS 13+。

https://developer.apple.com/documentation/swift/task

如果您需要使用async呼叫,请将呼叫包装起来Task

.onAppear(){
    Task{
        //Your async code here
        // await yourFuncHere()
    }
}     
Run Code Online (Sandbox Code Playgroud)

.onAppear有点不可靠,所以我可能会选择 an initof anObservableObject作为替代方案。


Zee*_* II 0

import SwiftUI

struct TaskEntry: Identifiable {
    let id = UUID()
    let title: String
    // Add other properties if needed
}

struct ContentView: View {
    
    @State var results = [TaskEntry]()
    @State private var dataTask: Task<Void, Error>?
  
    var body: some View {
        List(results, id: \.id) { item in
            VStack(alignment: .leading) {
                Text(item.title)
            }
        }
        .onAppear {
            dataTask = Task {
                do {
                    results = try await loadData()
                } catch {
                    print("Error loading data: \(error.localizedDescription)")
                    // Handle error accordingly
                }
            }
        }
        .onDisappear {
            dataTask?.cancel()
        }
    }
    
    func loadData() async throws -> [TaskEntry] {
        // Simulated asynchronous data fetching
        // Replace this with your actual data fetching logic
        
        // For now, returning an empty array as a placeholder
        return []
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑答案。