Search code examples
swiftreactive-programmingreactive-cocoareactive-swift

Reactive Swift Bindings for optional MutableProperty not getting set?


So I have recently started trying to incorporate ReactiveSwift into my project and I can't seem to figure out why this one portion of my code is giving me a compile error when I try to set the property with the <~ operator.

So here is what I have so far,

let bodyDetailViewModel = MutableProperty<BodyDetailViewModel?>(nil)

bodyManager = BodyManager()

let bodyDetailReadySignal = Signal.combineLatest(bodyManager.bodypartName.signal,
                                                     bodyManager.bodypartDetail.signal,
                                                     bodyManager.bodypartThumbnail.signal,
                                                     bodyManager.bodypartHighlighted.signal)

bodyDetailViewModel <~ bodyDetailReadySignal.map {
    if $3 == nil { return nil } // this line says Nil is incompatible with BodyDetailViewModel
    return BodyDetailViewModel(name: $0, detail: $1, thumbnail: $2, highlighted: $3!)
}

So as you can see above the line that gives me an error confuses me because I have set it to be an optional property so I don't understand why its saying a nil value is incompatible. Also if there are better ways of doing this please let me know as I find it hard to find resources for reactivecocoa for swift


Solution

  • This appears to be a Swift type-inference limitation. I can reproduce a similar error without using ReactiveSwift:

    let arr = [1, 2, 3, 4]
    
    let newArr = arr.map { elem in 
        if elem % 2 == 1 { return nil } 
        return elem / 2
    }
    

    In Swift 3.1.1 this gives the error "unable to infer complex closure return type; add explicit type to disambiguate".

    This works:

    let arr = [1, 2, 3, 4]
    
    let newArr = arr.map { elem -> Int? in 
        if elem % 2 == 1 { return nil } 
        return elem / 2
    }
    

    So try adding -> BodyDetailViewModel? to your closure definition and see if that works.