Reactivecocoa: Can't bind Signal and mutableProperty to Disposable.

Created on 25 Sep 2017  ·  6Comments  ·  Source: ReactiveCocoa/ReactiveCocoa

Recently, I updated to xcode9.
it occurred error message ‘Module compiled with Swift 3.1 cannot be imported in Swift 3.2

So I open a Terminal and type a command advice.

carthage update --platform iOS --no-use-binaries

It may resolve error, but Xcode constantly tell me about syntax error which is “generic parameter 'u' could not be inferred”

Here is my error code

func bindingData(viewModel: ItemTypeListViewModel) {
      self.disposable.dispose()
      let disposable = CompositeDisposable()
      self.disposable = disposable

      disposable += buttonModels <~ viewModel.types.take(during: reactive.lifetime).map {
           $0.enumerated().map {
                ItemTypeButtonModelImpl($1, isPressed: viewModel.selectType, index: $0)
           }
      }
 }       

Error line is here. In the line, Xcode showed me 'the red line' with syntax error message
generic parameter 'u' could not be inferred

disposable += buttonModel <~ /*<- this operator */ viewModel.type.take(...

It is my Cartfile.resolve's part of detail.

    github "ReactiveCocoa/ReactiveCocoa" "5.0.3"
    github "ReactiveCocoa/ReactiveSwift" "1.1.3"
    github "ReactiveX/RxSwift" "3.6.1"
    github "antitypical/Result" "3.2.3"

```swift
precedencegroup BindingPrecedence {
associativity: right
higherThan: AssignmentPrecedence
}

infix operator <~ : BindingPrecedence

/// Binds a source to a target, updating the target's value to the latest
/// value sent by the source.
///
/// - note: The binding will automatically terminate when the target is
/// deinitialized, or when the source sends a completed event.
///
/// /// let property = MutableProperty(0) /// let signal = Signal({ /* do some work after some time */ }) /// property <~ signal ///
///
/// /// let property = MutableProperty(0) /// let signal = Signal({ /* do some work after some time */ }) /// let disposable = property <~ signal /// ... /// // Terminates binding before property dealloc or signal's /// // `completed` event. /// disposable.dispose() ///
///
/// - parameters:
/// - target: A target to be bond to.
/// - source: A source to bind.
///
/// - returns: A disposable that can be used to terminate binding before the
/// deinitialization of the target or the source's completed
/// event.

public func <~(provider: Provider, source: Source) ->
Disposable? where Provider : BindingTargetProvider,
Source : BindingSource, Source.Error == Result.NoError,
Source.Value == Provider.Value

Here is link in stackoverflow.
[https://stackoverflow.com/questions/46389023/in-xcode9-with-reactiveswift-cant-bind-mutableproperty-and-signal-to-disposabl](https://stackoverflow.com/questions/46389023/in-xcode9-with-reactiveswift-cant-bind-mutableproperty-and-signal-to-disposabl)

This project was worked fine at Xcode 8.3.3. However I can’t build a project because of issues that I mentioned at Xcode9. Have you ever heard a problem like me? If you know about this problem, 
plz help me.
If you need more information, please give me a reply.
Thanks

**+add**

Another problem,
```swift
func bindingData(viewModel: ItemTypeListViewModel) {
      self.disposable.dispose()
      let disposable = CompositeDisposable()
      self.disposable = disposable

      let Signal = viewModel.types.take(during: reactive.lifetime).map {
           $0.enumerated().map {
                ItemTypeButtonModelImpl($1, isPressed: viewModel.selectType, index: $0)
           }
      }//ok       

      disposable += buttonModels <~ Signal 
    //Expression type 'Disposable?' is ambiguous without more context
}

In this case, shows "Expression type 'Disposable?' is ambiguous without more context" alert message with red line.
Am I mistaken for 'How to Use bind'?
If you know about this problem, plz help me.
Thanks!!

+add

protocol ItemTypeButtonModel {
    var type: ItemType { get }
    var isPressed: Action<Void, ItemTypeContext?, NoError> { get }
    var isSelected: MutableProperty<Bool> { get }
}

class ItemTypeButtonModelImpl: ItemTypeButtonModel {
    let type: ItemType
    let isSelected = MutableProperty<Bool>(false)
    let isPressed: Action<Void, ItemTypeSelectContext?, NoError>
    init(_ type: ItemType, isPressed: Action<ItemTypeContext, ItemTypeContext?, NSError>, index: Int) {
        self.type = type
        self.isPressed = Action { _ -> SignalProducer<ItemTypeContext?, NoError> in
            return isPressed.apply(ItemTypeContext(type: type, index: index)).flatMapError{ _ in .empty }
        }
    }
}

Here is ButtonModel and ViewModel.type !

ButtonModel is MutableProperty<[ItemTypeButtonModel]>
ViewModel.type is Signal<[ItemTypeButtonModelImpl], NoError>

Most helpful comment

Could you try to add as ItemTypeButtonModel after instantiating ItemTypeButtonModelImpl?

All 6 comments

What is the type of buttonModels and viewModel.types? It could be due to the types on both ends of <~ not matching with each other.

I added type information!
but, I think buttonModels and viewModel.types match.
ItemTypeButtonModelImpl has ItemTypeButtonModel's protocol

Could you try to add as ItemTypeButtonModel after instantiating ItemTypeButtonModelImpl?

Working well!
Thank you for your help! thank you!

It is kinda odd because coercing [C] to [P] given that C conforms to P works, just that it isn’t a generic environment like this binding. I guess this is a regression of Swift 3.2/4.0 if it did work in 3.1.

I absolutely agree with you.
I thought it was 'bug of Xcode9 with 3.2'...
Anyway, thanks again, Mr. andersio!
Have a nice day.

Was this page helpful?
0 / 5 - 0 ratings