ReactiveX / RxSwift

Reactive Programming in Swift
MIT License
24.37k stars 4.17k forks source link

Observing UserDefaults fails when key contains dots #1478

Closed xxtesaxx closed 6 years ago

xxtesaxx commented 7 years ago

Short description of the issue:

Observing UserDefaults fails if key contains a dot

Expected outcome:

Observing UserDefaults works with any kind of text as key (e.g. com.myapp.mykey)

What actually happens:

After subscribing, onNext is called only once but never again.

Self contained code example that reproduces the issue:

          //Does not work
        let observer1 = UserDefaults.standard.rx.observe(String.self, "com.myapp.mykey")
        observer1.subscribe(onNext: { (myString) in
            print("myString1 is \(myString)")
        }).disposed(by: disposeBag)

        DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
            UserDefaults.standard.set("Test", forKey: "com.myapp.mykey")
        })

        //Does work
        let observer2 = UserDefaults.standard.rx.observe(String.self, "com_myapp_mykey")
        observer2.subscribe(onNext: { (myString) in
            print("myString2 is \(myString)")
        }).disposed(by: disposeBag)

        DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
            UserDefaults.standard.set("Test", forKey: "com_myapp_mykey")
        })

        //Console output
        myString1 is nil
        myString2 is nil
        myString2 is Optional("Test")
        myString2 is Optional("Test")

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

4.0.0

Platform/Environment

How easy is to reproduce? (chances of successful reproduce after running the self contained code)

Xcode version:

  9.0.1

Installation method:

I have multiple versions of Xcode installed: (so we can know if this is a potential cause of your issue)

Level of RxSwift knowledge: (this is so we can understand your level of knowledge and formulate the response in an appropriate manner)

kzaher commented 6 years ago

Hi @xxtesaxx ,

This is by design, or better to say, a consequence of choice that dots separate property names.

I don't see any obvious way how to change this without changing the public interface.

I think we could have potentially made this interface better in past by designing it something like.

UserDefaults.standard.rx.observe(String.self, "com", "myapp", "mykey")

... but at the time I thought that using a consistent format was a better idea.

xxtesaxx commented 6 years ago

Ah I see. I didn't know that. Must have missed it in the documentation. Thanks for letting me know that this is not actually a bug. I'm now going with underscores instead of dots. I guess since its only my app which can access the defaults it wouldn't even matter to use the vendor prefix, right?