Это перевод статьи Concurrency Step-by-Step: Stateful Systems
В предыдущих первом и во втором постах я использовал исключительно систему только для чтения. Это далеко от реальных задач! Реальные приложения пишут данные в локальное хранилище, в удаленные сервисы и, как правило, находятся «по самые уши» в изменяемом состоянии.
В этом посте мы собираемся создать приложение SwiftUI, которое работает с изменяемым состоянием, размещенным на (мнимой) удаленной сетевой службе.
Краткие заметки
Как и во всех предыдущих постах этой серии, я буду игнорировать ошибки и требовать Xcode 16. Я также остаюсь новичком в SwiftUI, а здесь больше SwiftUI, чем в других постах.
Еще одно важное замечание заключается в том, что я пытался найти подходящую бесплатную удаленную службу, но безуспешно. Сначала я думал, что это будет решающим фактором. Но потом я понял, что это может быть счастливой случайностью. Читайте дальше, чтобы узнать почему!
«Удаленная» (‘remote’) система
Для начала нам нужна какая-то удаленная (remote) служба для взаимодействия. Весь смысл этого упражнения — иметь дело с состоянием, поэтому важно, чтобы эта система сохраняла состояние. Но я не смог ее найти, поэтому мы просто притворимся.
final class RemoteSystem: @unchecked Sendable {
private var state = false
private let queue = DispatchQueue(label: "RemoteSystemQueue")
func toggleState(completionHandler: @escaping @Sendable () -> Void) {
queue.async {
self.state.toggle()
completionHandler()
}
}
func readState(completionHandler: @escaping @Sendable (Bool) -> Void) {
queue.async {
completionHandler(self.state)
}
}
}Это симуляция “удаленной” системы, которая управляет значением ровно одной булевой Bool переменной var state. Внешний мир может переключать или считывать текущее булевское Bool значение этой переменной state, но он должен делать это асинхронно.
Я уверен, вы также заметили, что я решил реализовать это с помощью Dispatch. Чтобы это работало со Swift 6, мы должны сообщить компилятору, что мы взяли на себя ответственность за потокобезопасность, отметив ТИП RemoteSystem как @unchecked Sendable. Нам также нужно несколько @Sendable замыканий.







