.task(id:) хорош для экрана, где загрузка зависит от параметра. Главное: не забыть, что старый task отменяется при смене id.Типичный пример: экран профиля получает
userID, грузит данные и должен перезапускать запрос при смене пользователя. Для этого не нужен ручной onAppear плюс отдельный флаг загрузки.
struct ProfileView: View {
let userID: User.ID
@State private var profile: Profile?
@State private var error: Error?
var body: some View {
Content(profile: profile, error: error)
.task(id: userID) {
do {
profile = try await api.profile(for: userID)
error = nil
} catch is CancellationError {
// Новый userID уже запустил следующий task.
} catch {
self.error = error
}
}
}
}
При смене
userID SwiftUI отменит старую задачу и начнет новую. Это удобно для search, detail screens и preview states, где значение id описывает загрузку.Ограничение: ваш async-код должен уважать cancellation. Если внутри обёртка над старым callback API, добавьте отмену сами или хотя бы проверяйте
Task.isCancelled перед записью в state.Источник: Apple Documentation, View.task
#Swift #SwiftUI #Concurrency #iOS #AsyncAwait