Skip to content

Instantly share code, notes, and snippets.

@IanKeen
Created April 6, 2016 18:36
Show Gist options
  • Save IanKeen/a4640b1e52474c17ee9bfa258e667233 to your computer and use it in GitHub Desktop.
Save IanKeen/a4640b1e52474c17ee9bfa258e667233 to your computer and use it in GitHub Desktop.
Allow a more concise way to weakly subscribe to Observables using self.someFunction
//
// ObservableType+Weak.swift
//
// Created by Ian Keen on 6/04/2016.
// Copyright © 2016 Ian Keen. All rights reserved.
//
import Foundation
import RxSwift
extension ObservableType {
/**
Leverages instance method currying to provide a weak wrapper around an instance function
- parameter obj: The object that owns the function
- parameter method: The instance function represented as `InstanceType.instanceFunc`
*/
private func weakify<A: AnyObject, B>(obj: A, method: ((A) -> (B) -> Void)?) -> ((B) -> Void) {
return { [weak obj] value in
guard let obj = obj else { return }
method?(obj)(value)
}
}
/**
Subscribes an event handler to an observable sequence.
- parameter obj: Weakly referenced object containing the target function.
- parameter on: Function to invoke on `obj` for each event in the observable sequence.
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
@warn_unused_result(message="http://git.io/rxs.ud")
public func subscribe<A: AnyObject>(obj: A, _ on: (A) -> (RxSwift.Event<Self.E>) -> Void) -> Disposable {
return self.subscribe(weakify(obj, method: on))
}
/**
Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence.
- parameter obj: Weakly referenced object containing the target function.
- parameter onNext: Function to invoke on `obj` for each element in the observable sequence.
- parameter onError: Function to invoke on `obj` upon errored termination of the observable sequence.
- parameter onCompleted: Function to invoke on `obj` upon graceful termination of the observable sequence.
- parameter onDisposed: Function to invoke on `obj` upon any type of termination of sequence (if the sequence has
gracefully completed, errored, or if the generation is cancelled by disposing subscription)
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
@warn_unused_result(message="http://git.io/rxs.ud")
public func subscribe<A: AnyObject>(
obj: A,
onNext: ((A) -> (Self.E) -> Void)? = nil,
onError: ((A) -> (ErrorType) -> Void)? = nil,
onCompleted: ((A) -> () -> Void)? = nil,
onDisposed: ((A) -> () -> Void)? = nil) -> Disposable {
let disposable: Disposable
if let disposed = onDisposed {
disposable = AnonymousDisposable(weakify(obj, method: disposed))
}
else {
disposable = NopDisposable.instance
}
let observer = AnyObserver { (e: RxSwift.Event<Self.E>) in
switch e {
case .Next(let value):
self.weakify(obj, method: onNext)(value)
case .Error(let e):
self.weakify(obj, method: onError)(e)
disposable.dispose()
case .Completed:
self.weakify(obj, method: onCompleted)()
disposable.dispose()
}
}
return StableCompositeDisposable.create(
self.asObservable().subscribe(observer),
disposable
)
}
/**
Subscribes an element handler to an observable sequence.
- parameter obj: Weakly referenced object containing the target function.
- parameter onNext: Function to invoke on `obj` for each element in the observable sequence.
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
@warn_unused_result(message="http://git.io/rxs.ud")
public func subscribeNext<A: AnyObject>(obj: A, _ onNext: (A) -> (Self.E) -> Void) -> Disposable {
return self.subscribeNext(weakify(obj, method: onNext))
}
/**
Subscribes an error handler to an observable sequence.
- parameter obj: Weakly referenced object containing the target function.
- parameter onError: Function to invoke on `obj` upon errored termination of the observable sequence.
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
@warn_unused_result(message="http://git.io/rxs.ud")
public func subscribeError<A: AnyObject>(obj: A, _ onError: (A) -> (ErrorType) -> Void) -> Disposable {
return self.subscribeError(weakify(obj, method: onError))
}
/**
Subscribes a completion handler to an observable sequence.
- parameter obj: Weakly referenced object containing the target function.
- parameter onCompleted: Function to invoke on `obj` graceful termination of the observable sequence.
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
@warn_unused_result(message="http://git.io/rxs.ud")
public func subscribeCompleted<A: AnyObject>(obj: A, _ onCompleted: (A) -> () -> Void) -> Disposable {
return self.subscribeCompleted(weakify(obj, method: onCompleted))
}
}
class Foo {
let obs: Observable<String>!
func addBindings() {
self.obs.subscribeNext(self, Foo.handleString)
/* Instead of
self.obs.subscribeNext { [weak self] string in
self.handleString(string)
}
*/
}
func handleString(string: String) {
/* ... */
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment