Skip to content

Commit

Permalink
Add withUnretained for SharedSequence (Driver, Signal)
Browse files Browse the repository at this point in the history
  • Loading branch information
freak4pc committed Jan 1, 2021
1 parent 000c0e6 commit e3f3401
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 3 deletions.
1 change: 1 addition & 0 deletions .jazzy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ custom_categories:
- Using
- Window
- WithLatestFrom
- WithUnretained
- Zip+Collection
- Zip+arity
- Zip
Expand Down
31 changes: 31 additions & 0 deletions RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,37 @@ extension SharedSequence {
}
}

// MARK: - withUnretained
extension SharedSequenceConvertibleType {
/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
In the case the provided object cannot be retained successfully, the seqeunce will complete.
- parameter obj: The object to provide an unretained reference on.
- parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence.
- returns: An observable sequence that contains the result of `resultSelector` being called with an unretained reference on `obj` and the values of the original sequence.
*/
public func withUnretained<Object: AnyObject, Out>(
_ obj: Object,
resultSelector: @escaping (Object, Element) -> Out
) -> SharedSequence<SharingStrategy, Out> {
SharedSequence(self.asObservable().withUnretained(obj, resultSelector: resultSelector))
}

/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
In the case the provided object cannot be retained successfully, the seqeunce will complete.
- parameter obj: The object to provide an unretained reference on.
- returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence.
*/
public func withUnretained<Object: AnyObject>(_ obj: Object) -> SharedSequence<SharingStrategy, (Object, Element)> {
withUnretained(obj) { ($0, $1) }
}
}

// MARK: withLatestFrom
extension SharedSequenceConvertibleType {

Expand Down
5 changes: 3 additions & 2 deletions RxSwift/Observables/WithUnretained.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ extension ObservableType {
*/
public func withUnretained<Object: AnyObject, Out>(
_ obj: Object,
resultSelector: @escaping ((Object, Element)) -> Out
resultSelector: @escaping (Object, Element) -> Out
) -> Observable<Out> {
map { [weak obj] element -> Out in
guard let obj = obj else { throw UnretainedError.failedRetaining }

return resultSelector((obj, element))
return resultSelector(obj, element)
}
.catch{ error -> Observable<Out> in
guard let unretainedError = error as? UnretainedError,
Expand All @@ -35,6 +35,7 @@ extension ObservableType {
}
}


/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
Expand Down
61 changes: 61 additions & 0 deletions RxSwift/Traits/Infallible/Infallible+Operators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -644,3 +644,64 @@ extension InfallibleType {
Infallible(asObservable().share(replay: replay, scope: scope))
}
}

// MARK: - withUnretained
extension InfallibleType {
/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
In the case the provided object cannot be retained successfully, the seqeunce will complete.
- parameter obj: The object to provide an unretained reference on.
- parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence.
- returns: An observable sequence that contains the result of `resultSelector` being called with an unretained reference on `obj` and the values of the original sequence.
*/
public func withUnretained<Object: AnyObject, Out>(
_ obj: Object,
resultSelector: @escaping (Object, Element) -> Out
) -> Infallible<Out> {
Infallible(self.asObservable().withUnretained(obj, resultSelector: resultSelector))
}

/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
In the case the provided object cannot be retained successfully, the seqeunce will complete.
- parameter obj: The object to provide an unretained reference on.
- returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence.
*/
public func withUnretained<Object: AnyObject>(_ obj: Object) -> Infallible<(Object, Element)> {
withUnretained(obj) { ($0, $1) }
}
}

extension InfallibleType {
// MARK: - withLatestFrom
/**
Merges two observable sequences into one observable sequence by combining each element from self with the latest element from the second source, if any.
- seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html)
- note: Elements emitted by self before the second source has emitted any values will be omitted.
- parameter second: Second observable source.
- parameter resultSelector: Function to invoke for each element from the self combined with the latest element from the second source, if any.
- returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function.
*/
public func withLatestFrom<Source: InfallibleType, ResultType>(_ second: Source, resultSelector: @escaping (Element, Source.Element) throws -> ResultType) -> Infallible<ResultType> {
Infallible(self.asObservable().withLatestFrom(second.asObservable(), resultSelector: resultSelector))
}

/**
Merges two observable sequences into one observable sequence by using latest element from the second sequence every time when `self` emits an element.
- seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html)
- note: Elements emitted by self before the second source has emitted any values will be omitted.
- parameter second: Second observable source.
- returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function.
*/
public func withLatestFrom<Source: InfallibleType>(_ second: Source) -> Infallible<Source.Element> {
withLatestFrom(second) { $1 }
}
}
1 change: 1 addition & 0 deletions Sources/AllTestz/Observable+WithUnretainedTests.swift
16 changes: 16 additions & 0 deletions Sources/AllTestz/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2146,6 +2146,21 @@ final class VirtualSchedulerTest_ : VirtualSchedulerTest, RxTestCase {
("testVirtualScheduler_stress", VirtualSchedulerTest.testVirtualScheduler_stress),
] }
}

final class WithUnretainedTests_ : WithUnretainedTests, RxTestCase {
#if os(macOS)
required override init() {
super.init()
}
#endif

static var allTests: [(String, (WithUnretainedTests_) -> () -> Void)] { return [
("testObjectAttached", WithUnretainedTests.testObjectAttached),
("testObjectDeallocates", WithUnretainedTests.testObjectDeallocates),
("testObjectDeallocatesSequenceCompletes", WithUnretainedTests.testObjectDeallocatesSequenceCompletes),
("testResultsSelector", WithUnretainedTests.testResultsSelector),
] }
}
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)

func testCase<T: RxTestCase>(_ tests: [(String, (T) -> () -> Void)]) -> () -> Void {
Expand Down Expand Up @@ -2262,5 +2277,6 @@ func XCTMain(_ tests: [() -> Void]) {
testCase(SignalTests_.allTests),
testCase(SingleTest_.allTests),
testCase(VirtualSchedulerTest_.allTests),
testCase(WithUnretainedTests_.allTests),
])
//}
1 change: 1 addition & 0 deletions Sources/RxSwift/WithUnretained.swift
2 changes: 1 addition & 1 deletion Tests/RxSwiftTests/Observable+WithUnretainedTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// Observable+WithUnretainedTests.swift
// RxSwift
// Tests
//
// Created by Vincent Pradeilles on 01/01/2021.
// Copyright © 2021 Krunoslav Zaher. All rights reserved.
Expand Down

0 comments on commit e3f3401

Please sign in to comment.