Skip to content

Commit e3f3401

Browse files
committed
Add withUnretained for SharedSequence (Driver, Signal)
1 parent 000c0e6 commit e3f3401

File tree

8 files changed

+115
-3
lines changed

8 files changed

+115
-3
lines changed

.jazzy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ custom_categories:
242242
- Using
243243
- Window
244244
- WithLatestFrom
245+
- WithUnretained
245246
- Zip+Collection
246247
- Zip+arity
247248
- Zip

RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,37 @@ extension SharedSequence {
443443
}
444444
}
445445

446+
// MARK: - withUnretained
447+
extension SharedSequenceConvertibleType {
448+
/**
449+
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
450+
451+
In the case the provided object cannot be retained successfully, the seqeunce will complete.
452+
453+
- parameter obj: The object to provide an unretained reference on.
454+
- parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence.
455+
- 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.
456+
*/
457+
public func withUnretained<Object: AnyObject, Out>(
458+
_ obj: Object,
459+
resultSelector: @escaping (Object, Element) -> Out
460+
) -> SharedSequence<SharingStrategy, Out> {
461+
SharedSequence(self.asObservable().withUnretained(obj, resultSelector: resultSelector))
462+
}
463+
464+
/**
465+
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
466+
467+
In the case the provided object cannot be retained successfully, the seqeunce will complete.
468+
469+
- parameter obj: The object to provide an unretained reference on.
470+
- returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence.
471+
*/
472+
public func withUnretained<Object: AnyObject>(_ obj: Object) -> SharedSequence<SharingStrategy, (Object, Element)> {
473+
withUnretained(obj) { ($0, $1) }
474+
}
475+
}
476+
446477
// MARK: withLatestFrom
447478
extension SharedSequenceConvertibleType {
448479

RxSwift/Observables/WithUnretained.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ extension ObservableType {
1818
*/
1919
public func withUnretained<Object: AnyObject, Out>(
2020
_ obj: Object,
21-
resultSelector: @escaping ((Object, Element)) -> Out
21+
resultSelector: @escaping (Object, Element) -> Out
2222
) -> Observable<Out> {
2323
map { [weak obj] element -> Out in
2424
guard let obj = obj else { throw UnretainedError.failedRetaining }
2525

26-
return resultSelector((obj, element))
26+
return resultSelector(obj, element)
2727
}
2828
.catch{ error -> Observable<Out> in
2929
guard let unretainedError = error as? UnretainedError,
@@ -35,6 +35,7 @@ extension ObservableType {
3535
}
3636
}
3737

38+
3839
/**
3940
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
4041

RxSwift/Traits/Infallible/Infallible+Operators.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,3 +644,64 @@ extension InfallibleType {
644644
Infallible(asObservable().share(replay: replay, scope: scope))
645645
}
646646
}
647+
648+
// MARK: - withUnretained
649+
extension InfallibleType {
650+
/**
651+
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
652+
653+
In the case the provided object cannot be retained successfully, the seqeunce will complete.
654+
655+
- parameter obj: The object to provide an unretained reference on.
656+
- parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence.
657+
- 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.
658+
*/
659+
public func withUnretained<Object: AnyObject, Out>(
660+
_ obj: Object,
661+
resultSelector: @escaping (Object, Element) -> Out
662+
) -> Infallible<Out> {
663+
Infallible(self.asObservable().withUnretained(obj, resultSelector: resultSelector))
664+
}
665+
666+
/**
667+
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
668+
669+
In the case the provided object cannot be retained successfully, the seqeunce will complete.
670+
671+
- parameter obj: The object to provide an unretained reference on.
672+
- returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence.
673+
*/
674+
public func withUnretained<Object: AnyObject>(_ obj: Object) -> Infallible<(Object, Element)> {
675+
withUnretained(obj) { ($0, $1) }
676+
}
677+
}
678+
679+
extension InfallibleType {
680+
// MARK: - withLatestFrom
681+
/**
682+
Merges two observable sequences into one observable sequence by combining each element from self with the latest element from the second source, if any.
683+
684+
- seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html)
685+
- note: Elements emitted by self before the second source has emitted any values will be omitted.
686+
687+
- parameter second: Second observable source.
688+
- parameter resultSelector: Function to invoke for each element from the self combined with the latest element from the second source, if any.
689+
- 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.
690+
*/
691+
public func withLatestFrom<Source: InfallibleType, ResultType>(_ second: Source, resultSelector: @escaping (Element, Source.Element) throws -> ResultType) -> Infallible<ResultType> {
692+
Infallible(self.asObservable().withLatestFrom(second.asObservable(), resultSelector: resultSelector))
693+
}
694+
695+
/**
696+
Merges two observable sequences into one observable sequence by using latest element from the second sequence every time when `self` emits an element.
697+
698+
- seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html)
699+
- note: Elements emitted by self before the second source has emitted any values will be omitted.
700+
701+
- parameter second: Second observable source.
702+
- 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.
703+
*/
704+
public func withLatestFrom<Source: InfallibleType>(_ second: Source) -> Infallible<Source.Element> {
705+
withLatestFrom(second) { $1 }
706+
}
707+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../Tests/RxSwiftTests/Observable+WithUnretainedTests.swift

Sources/AllTestz/main.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,21 @@ final class VirtualSchedulerTest_ : VirtualSchedulerTest, RxTestCase {
21462146
("testVirtualScheduler_stress", VirtualSchedulerTest.testVirtualScheduler_stress),
21472147
] }
21482148
}
2149+
2150+
final class WithUnretainedTests_ : WithUnretainedTests, RxTestCase {
2151+
#if os(macOS)
2152+
required override init() {
2153+
super.init()
2154+
}
2155+
#endif
2156+
2157+
static var allTests: [(String, (WithUnretainedTests_) -> () -> Void)] { return [
2158+
("testObjectAttached", WithUnretainedTests.testObjectAttached),
2159+
("testObjectDeallocates", WithUnretainedTests.testObjectDeallocates),
2160+
("testObjectDeallocatesSequenceCompletes", WithUnretainedTests.testObjectDeallocatesSequenceCompletes),
2161+
("testResultsSelector", WithUnretainedTests.testResultsSelector),
2162+
] }
2163+
}
21492164
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
21502165

21512166
func testCase<T: RxTestCase>(_ tests: [(String, (T) -> () -> Void)]) -> () -> Void {
@@ -2262,5 +2277,6 @@ func XCTMain(_ tests: [() -> Void]) {
22622277
testCase(SignalTests_.allTests),
22632278
testCase(SingleTest_.allTests),
22642279
testCase(VirtualSchedulerTest_.allTests),
2280+
testCase(WithUnretainedTests_.allTests),
22652281
])
22662282
//}

Sources/RxSwift/WithUnretained.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../RxSwift/Observables/WithUnretained.swift

Tests/RxSwiftTests/Observable+WithUnretainedTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//
22
// Observable+WithUnretainedTests.swift
3-
// RxSwift
3+
// Tests
44
//
55
// Created by Vincent Pradeilles on 01/01/2021.
66
// Copyright © 2021 Krunoslav Zaher. All rights reserved.

0 commit comments

Comments
 (0)