В SwiftUI удобно использовать .task: он запускает асинхронную загрузку при появлении представления и связывает отмену с его жизненным циклом.
Инициация получения данных при отображении экрана
В SwiftUI удобно использовать .task: он запускает асинхронную загрузку при появлении представления и связывает отмену с его жизненным циклом.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Связать сервис NetworkService с представлением HomeView и при появлении этого представления запустить асинхронный метод fetchData() для загрузки нужных данных.
final class NetworkService {
func fetchData() async throws -> Int {
return 5
}
}
Ответ
В SwiftUI удобно использовать .task: он запускает асинхронную загрузку при появлении представления и связывает отмену с его жизненным циклом.
Пример для данного простого сервиса; его изоляцию следует согласовать с ViewModel/проектом:
@MainActor
struct HomeView: View {
let service: NetworkService
@State private var value: Int?
@State private var errorMessage: String?
var body: some View {
Group {
if let value { Text("Number is: \(value)") }
else if let errorMessage { Text(errorMessage) }
else { ProgressView() }
}
.task {
do {
let result = try await service.fetchData()
try Task.checkCancellation()
value = result
} catch is CancellationError {
// Ушедший экран не получает сообщение об ошибке.
} catch { errorMessage = error.localizedDescription }
}
}
}
Для строгой конкурентности показанный сервис без состояния можно сделать Sendable либо изолировать MainActor. .task может запуститься снова при новом появлении: кеширование и политику повторной загрузки определяют отдельно.