How to use BehaviorRelay as an alternate to Variable in RxSwift?

后端 未结 8 1878
无人共我
无人共我 2021-01-30 03:52

As of RxSwift4, Variable is moved to Deprecated.swift marking the possible deprecation of Variable in future. An alternate proposed to

相关标签:
8条回答
  • 2021-01-30 04:20

    AshKan answer is great but I came here looking for a missing method from the solution. Append:

    extension BehaviorRelay where Element: RangeReplaceableCollection {
            
        func append(_ subElement: Element.Element) {
            var newValue = value
            newValue.append(subElement)
            accept(newValue)
        }
    }
    
    0 讨论(0)
  • 2021-01-30 04:21

    How about this kind of extension:

    extension BehaviorRelay {
    
        var val: Element {
            get { value }
            set { accept(newValue) }
        }
    }
    

    Then use it as you were using the Variable, but instead of calling value, call val:

    myFilter.val.append(newModel)
    
    0 讨论(0)
  • 2021-01-30 04:32

    I would do something like that -

    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)
    
    0 讨论(0)
  • 2021-01-30 04:34

    I created those this extension, with two methods to facilitate migration in case you have a Variable of Array and you have to use append.

        extension BehaviorRelay where Element: RangeReplaceableCollection {
    
            func append(_ subElement: Element.Element) {
                var newValue = value
                newValue.append(subElement)
                accept(newValue)
            }
    
            func append(contentsOf: [Element.Element]) {
                var newValue = value
                newValue.append(contentsOf: contentsOf)
                accept(newValue)
            }
    
            public func remove(at index: Element.Index) {
                var newValue = value
                newValue.remove(at: index)
                accept(newValue)
            }
    
            public func removeAll() {
                var newValue = value
                newValue.removeAll()
                accept(newValue)
            }
    
        }
    

    and you call it like this

        var things = BehaviorRelay<[String]>(value: [])
        things.append("aa")
        let otherThings = ["bb", "cc"]
        things.append(contentsOf: otherThings) 
        things.remove(at: 0)
        things.removeAll()
    
    0 讨论(0)
  • 2021-01-30 04:34

    On Variable used to have:

    let variable = Variable("Hello RxSwift")
    variable.value = "Change text" 
    print(variable.value) // "Change text"
    

    On BehaviorRelay you have to use:

    let relay = BehaviorRelay(value: "Hello RxSwift")
    relay.accept("Change text")
    print(relay.value) // "Change text"
    
    0 讨论(0)
  • 2021-01-30 04:35

    Have you considered simply creating a new array from the existing value on the relay, appending, then calling accept?

    myFilter.accept(myFilter.value + [newModel])
    
    0 讨论(0)
提交回复
热议问题