ios11 - react - rxswift docs
¿Cómo usar BehaviorRelay como una alternativa a la variable en RxSwift? (3)
A partir de RxSwift4, la Variable
se mueve a Deprecated.swift
marcando la posible desaprobación de la Variable
en el futuro. Una alternativa propuesta para Variable
es BehaviorRelay
. Al publicar esta pregunta, como no pude encontrar gran parte del tutorial en la web usando BehaviorRelay
estoy publicando una pregunta tan fundamental aquí en SO.
Supongamos que tengo una llamada de servicio web en curso y recibo una parte de los datos que es JSONArray, al analizar el objeto JSON uno por uno, actualizo la propiedad de valor de mi variable
Aquí está mi declaración de variable
var myFilter = Variable<[MyFilterModel]>([MyFilterModel(data: "{:}")])
en la obtención de un nuevo elemento cada vez que actualizaría mi variable como
myFilter.value.append(newModel)
Como Variable estaba vinculada a CollectionView, collectionVie actualizaría su IU inmediatamente con el objeto recién agregado.
Problema con BehaviorRelay
Ahora mi declaración parece
var myFilter = BehaviorRelay<[MyFilterModel]>(value: [MyFilterModel(data: "{:}")])
Pero el mayor problema es que myFilter.value
es readOnly . Tan obviamente
myFilter.value.append(newModel)
no es una solucion Me di cuenta de que puedo usar accept
más bien.
Pero ahora, cuando intento analizar cada elemento en respuesta y actualizar el valor de myFilter
self?.expertsFilter.accept(newModel)
La declaración anterior da error de cotización
No se puede convertir el valor de NewModel al tipo de argumento esperado [NewModel]
Obviamente, se espera una matriz y no un elemento individual.
Solución:
Solución 1:
Entonces, ¿una solución es acumular toda la respuesta en una matriz temporal y, una vez hecho esto, desencadenar el self?.expertsFilter.accept(temporary_array)
Solución 2:
Si tengo que enviar el onNext
evento al suscriptor al analizar cada elemento, debo copiar el valor de self? .ExpertsFilter en la nueva matriz, agregarle el nuevo elemento analizado y devolver la nueva matriz.
Solución 3:
Deshágase de BehaviorRelay
y use BehaviorSubject
/ PublishSubject
Los primeros dos sonidos son deprimentes, ya que puede ser necesario activar la IU al analizar cada elemento que no puedo esperar hasta que se analice la respuesta completa. Así que obviamente la solución 1 no es de mucha utilidad.
La segunda solución es mucho más horrible porque crea una nueva matriz (sé que es temporal y se lanzará) cada vez que se envíe el siguiente evento.
Pregunta:
Debido a que BehaviorRelay
se propone como una alternativa a la Variable
estoy en un dilema, ¿estoy utilizando accept
correctamente? ¿Hay una mejor manera de resolverlo?
Por favor ayuda
¿Ha considerado simplemente la creación de una nueva matriz a partir del valor existente en el relevo, anexando y luego llamando a accept
?
myFilter.accept(myFilter.value + [newModel])
Sobre la base de la respuesta de Dalton , aquí hay una extensión útil:
extension BehaviorRelay where Element: RangeReplaceableCollection {
func acceptAppending(_ element: Element.Element) {
accept(value + [element])
}
}
Yo haría algo así.
let requests = PublishSubject<Observable<ServerResponse>>.create()
let responses: Observable<ServerResponse> = requests.switchLatest()
let parsed: Observable<[ParsedItem]> = responses
.flatMap { Observable.from($0).map { parse($0) }.toArray() }
parsed.bind(to: ui)
// repeated part
let request1: Observable<ServerResponse> = servive.call()
request.onNext(request1)