ReactiveX / RxSwift

Reactive Programming in Swift
MIT License
24.36k stars 4.16k forks source link

Type 'inout UITextField' does not conform to protocol 'ReactiveCompatible' #944

Closed Dharin-shah closed 7 years ago

Dharin-shah commented 7 years ago

:warning: If you don't have something to report in the following format, it will probably be easier and faster to ask in the slack channel first. :warning:

Short description of the issue: Previously in swift 2.x I was using someTextField.rx_text

Then it Changed to (in swift 3.0 update) someTextField.rx.textInput.text

But now it is giving me this error

when I updated (from pods) RxCocoa 3.0.0-rc.1 (was 3.0.0-beta.2) RxSwift 3.0.0-rc.1 (was 3.0.0-beta.2)

// If we can't get a self contained code example that reproduces the issue, there is a big chance we won't be able // to help you because there is not much we can do. // Self contained code example means: // * that we should be able to just run the provided code without changing it. // * that it will reproduce the issue upon running


**Xcode version**:

Xcode version goes here


**Expected outcome**:

  _what you expect to happen goes here_

**What actually happens**:

  _what actually happens goes here_

:warning: Fields below are optional for general issues or in case those questions aren't related to your issue, but filling them out will increase the chances of getting your issue resolved. :warning:

**Installation method**:
  - [*] CocoaPods
  - [ ] Carthage
  - [ ] Git submodules

**I have multiple versions of Xcode installed**:
  (so we can know if this is a potential cause of your issue)
  - [ ] yes (which ones)
  - [*] no

**Level of RxSwift knowledge**:
  (this is so we can understand your level of knowledge
    and formulate the response in an appropriate manner)
  - [ ] just starting
  - [ ] I have a small code base
  - [*] I have a significant code base
Dharin-shah commented 7 years ago

RxCocoa now provides optional string. Which is why i was getting this error.

skywalkerlw commented 7 years ago

so what's the solution?

Dharin-shah commented 7 years ago

My function wasn't expecting a Driver of Optional String, which is why it game me this error. someTextfield.rx.text.asDriver() returns Driver<String?> someTextfield.rx.text returns Observable<String?>

skywalkerlw commented 7 years ago

SomeTextfield.rx.text() is not recognised. Appreciate if you could let me know how I can achieve it.

image

Dharin-shah commented 7 years ago

Whhoopsie, My Bad its just firstName.rx.text and not firstName.rx.text()

retX0 commented 7 years ago

I have the same issue, I copy the code from demo, I don`t understand why. how do you solve this problem

retX0 commented 7 years ago

Well, the demo`s parameter is Observable, but when textField.rx.text.asObservable() is Observable<String?>, so i modify the parameter to Observable<String?> , it working.

Dharin-shah commented 7 years ago

You can use the ControlProperty as an observable since it wraps an observable for that property. Therefore you can subscribe to it just as you subscribe to an Observable.

Here's a gist (commented in the code where ControlProperty is defined)

Initializes control property with a observable sequence that represents property values and observer that enables binding values to property.

 - parameter values: Observable sequence that represents property values.
 - parameter valueSink: Observer that enables binding values to control property.
 - returns: Control property created with a observable sequence of values and an observer that enables binding values
 to property.
retX0 commented 7 years ago

@Dharin-shah ,thanks, I`ll try this later, and there is any document to introduce how to extend Reactive for struct type?

aksswami commented 7 years ago

I am trying to get observable string from searchBar but I am constantly getting this error. Any help will be appreciated.

 var latestRepositoryName: Observable<String> {
        return searchBar.rx
            .text
            .throttle(0.5, scheduler: MainScheduler.instance)
            .distinctUntilChanged
    }

I am getting error Type 'inout UISearchBar' does not conform to protocol 'ReactiveCompatible'.

sergdort commented 7 years ago

Damn Swift compiler!! 😄 This is because rx.text is ControlProperty<String?> you need to apply map @kzaher I see a lot of confusion lately, because we decided to be consistent with UIKit, I remember we had a discussion with you about it in slack but I don't remember how it's ended 🙂

aksswami commented 7 years ago

Thanks @sergdort

Resolved it using RxOptional filterNil() transformer.

Dharin-shah commented 7 years ago

latestRepositoryName must be of type Observable<String?> or you must explicitely handle it here by using map function and passing you handler to handle optional string For eg:

var latestRepositoryName : Observable<String>{
        return searchBar.rx.text.throttle(0.5, scheduler : MainScheduler.instance).map(){text -> String in
           if(text == nil){
             return ""
          }else{
       return text!
   }

}
}
rlam3 commented 7 years ago

I'm having a similar issue with searchBar...

Was wondering if anybody could give me some pointers on this issue. I need to get the term from search bar and then launch a backend request to server then reload my data.

But I keep getting the following error on rx.text

'inout UISearchBar' does not conform to protocol 'ReactiveCompatible'
 // Rx 
    var latestSearchTerm: Observable<String?>{
        return searchBar.rx.text
            .throttle(0.5, scheduler: MainScheduler.instance)
            .distinctUntilChanged()
            .filterNil()
            .flatMap{ text in
                return text
            }
    }

I'm on XCode 8 and Swift 3

Thanks!

Dharin-shah commented 7 years ago

Filternil might be an issue Try removing it

rlam3 commented 7 years ago

@Dharin-shah Thanks for quick reply. I resolved it using the following:

But I'm not sure if this is the correct way to do it


    var latestSearchResults: Observable<String>{
        return searchBar.rx.text.orEmpty
            .throttle(0.5, scheduler: MainScheduler.instance)
            .distinctUntilChanged()
            .flatMap{ text -> Observable<String> in

                if text.isEmpty{
                    return .just("")
                }

                return .just(text)
            }
    }
Dharin-shah commented 7 years ago

Are you still returning observable<string?>

Dharin-shah commented 7 years ago

Oops my mistake

Dharin-shah commented 7 years ago

Why are you flat maping .. if you want string? Observable just return without the flat map and change the return type to string? Observable

rlam3 commented 7 years ago

@Dharin-shah Not sure what you are referring to. Do you mind showing me in a code comparison? Thanks!

Dharin-shah commented 7 years ago

Forgive me if i seem ignorant , its just that i am on my phone and cant really test . Once i get back to my laptop will surely check your code.

amirpervaiz086 commented 7 years ago

@xnxin meaning asObservable requires optional observable as input? as you said you changed it to <String?> I was facing same issue and had to convert my input observable to <String?> from . Just want to clear concept why it is required. Thanks in advance