En el imperativo Swift, es común usar propiedades calculadas para proporcionar un acceso conveniente a los datos sin duplicar el estado.
Digamos que tengo esta clase hecha para uso MVC imperativo:
class ImperativeUserManager {
private(set) var currentUser: User? {
didSet {
if oldValue != currentUser {
NotificationCenter.default.post(name: NSNotification.Name("userStateDidChange"), object: nil)
// Observers that receive this notification might then check either currentUser or userIsLoggedIn for the latest state
}
}
}
var userIsLoggedIn: Bool {
currentUser != nil
}
// ...
}
Si quiero crear un equivalente reactivo con Combine, por ejemplo, para usar con SwiftUI, puedo agregar fácilmente @Publisheda las propiedades almacenadas para generar Publishers, pero no para las propiedades calculadas.
@Published var userIsLoggedIn: Bool { // Error: Property wrapper cannot be applied to a computed property
currentUser != nil
}
Hay varias soluciones que se me ocurren. Podría hacer que mi propiedad calculada se almacene en su lugar y mantenerla actualizada.
Opción 1: Usar un observador de propiedades:
class ReactiveUserManager1: ObservableObject {
@Published private(set) var currentUser: User? {
didSet {
userIsLoggedIn = currentUser != nil
}
}
@Published private(set) var userIsLoggedIn: Bool = false
// ...
}
Opción 2: Usar a Subscriberen mi propia clase:
class ReactiveUserManager2: ObservableObject {
@Published private(set) var currentUser: User?
@Published private(set) var userIsLoggedIn: Bool = false
private var subscribers = Set<AnyCancellable>()
init() {
$currentUser
.map { $0 != nil }
.assign(to: \.userIsLoggedIn, on: self)
.store(in: &subscribers)
}
// ...
}
Sin embargo, estas soluciones alternativas no son tan elegantes como las propiedades calculadas. Duplican el estado y no actualizan ambas propiedades simultáneamente.
¿Cuál sería un equivalente apropiado para agregar Publishera una propiedad calculada en Combine?
ObservableObject. Inherentemente asume que un ObservableObjectobjeto debería tener una capacidad de mutación que, por definición, no es el caso de la propiedad calculada .