Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have you ever thought of making some adjustments to RxSwift? #165

Open
0x30 opened this issue Aug 25, 2018 · 7 comments
Open

Have you ever thought of making some adjustments to RxSwift? #165

0x30 opened this issue Aug 25, 2018 · 7 comments

Comments

@0x30
Copy link

0x30 commented Aug 25, 2018

Have you ever thought of making some adjustments to RxSwift?

Like the following?

import RxCocoa
import RxSwift

/// Maintain life cycle UnsafeRawPointer
private var keeplive = "defaultkeeplive"

extension DefaultsKey{
    
    private var keepLiveObservalue:NSObject?{
        set(newvalue){ objc_setAssociatedObject(self, &keeplive, newvalue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } // Save keep live obj
        get{ return nil } // In order to save trouble...
    }
    
    /// Make a Binder according to the DefaultsKey provided.
    /// Binder Value Type == DefailtsKey ValueType
    var binder:Binder<ValueType>{
        let keepliveobj = NSObject()
        self.keepLiveObservalue = keepliveobj
        return Binder(keepliveobj) { _, value in
            Defaults[self] = value
        }
    }
    
    /// Make a Observable according to the DefaultsKey provided.
    /// Observable Element Type == DefailtsKey ValueType
    var observable:Observable<ValueType>{
        return UserDefaults.standard.rx.observe(ValueType.self, self._key)
            .filter{ $0 != nil }.map{ $0! } // If you use RxOptional, it will be better.
    }
}
@radex
Copy link
Collaborator

radex commented Aug 30, 2018

Rx is fun! I think it would be inappropriate to have this as part of SwiftyUserDefaults, because there shouldn't be a forced dependency on RxSwift, but as an extension library — yeah!

@raphaeloliveira
Copy link

Extending on that, I'm facing issues because I'm using ReactiveSwift and its reactive extension won't use the default value provided on DefaultsKey initialiser. I'm happy to adapt my code but would be convenient if internal let defaultValue: ValueType? property would be public instead of internal.

@DivineDominion
Copy link
Contributor

I think making defaultValue public and read-only will be useful, too!

Also @0x30 what about an Rx extension in https://github.com/RxSwiftCommunity/ ?

@0x30
Copy link
Author

0x30 commented Apr 17, 2019

Ok, I may not express it very clearly, I hope I can get a configuration similar to Moya.

  s.subspec "ReactiveSwift" do |ss|
    ss.source_files = "Sources/ReactiveMoya/"
    ss.dependency "Moya/Core"
    ss.dependency "ReactiveSwift", "~> 5.0"
  end

  s.subspec "RxSwift" do |ss|
    ss.source_files = "Sources/RxMoya/"
    ss.dependency "Moya/Core"
    ss.dependency "RxSwift", "~> 4.0"
  end

@DivineDominion
Copy link
Contributor

Aha! Well, this would require the SwiftyUserDefaults maintainers to care for the reactive extensions, which is now only 2 people it seems. If they don't want to, and someone else starts with a RxSwiftCommunity repo, the extension can be maintained by a larger group of Rx fans, which makes the extension more resilient in the long term. (But will require you to import RxSwiftyUserDefaults on top of this library.)

@DivineDominion
Copy link
Contributor

This is how I started in my app during the v4.0 transition, btw:

extension Reactive where Base: UserDefaults {
    func observe<T: DefaultsSerializable>(key: DefaultsKey<T>, options: NSKeyValueObservingOptions = [.old, .new]) -> RxSwift.Observable<T.T?> {
        return Observable.create { observer -> Disposable in
            let token = self.base.observe(key: key, options: options) { update in
                observer.onNext(update.newValue)
            }
            return Disposables.create {
                token.dispose()
            }
        }
    }
}

@StevenSorial
Copy link

StevenSorial commented Jan 26, 2020

This is how I started in my app during the v4.0 transition

is there an updated sample for v5?

Edit: got it to work properly:

extension DefaultsAdapter {
  func observe<T: DefaultsSerializable>(_ key: DefaultsKey<T>,
                                        options: NSKeyValueObservingOptions = [.old, .new]
  ) -> RxSwift.Observable<DefaultsObserver<T>.Update> where T == T.T {
    Observable.create { observer in
      let token = self.observe(key, options: options) { update in
        observer.onNext(update)
      }
      return Disposables.create {
        token.dispose()
      }
    }
  }

  func observe<T: DefaultsSerializable>(_ keyPath: KeyPath<KeyStore, DefaultsKey<T>>,
                                        options: NSKeyValueObservingOptions = [.old, .new]
  ) -> RxSwift.Observable<DefaultsObserver<T>.Update> where T == T.T {
    Observable.create { observer in
      let token = self.observe(keyPath, options: options) { update in
        observer.onNext(update)
      }
      return Disposables.create {
        token.dispose()
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants