Slide 1

Slide 1 text

3Y4XJGUͱ3FBDUJWF4XJGU ൺֱͱಈ޲ ྛɹᚸ࢘ $"4XJGU

Slide 2

Slide 2 text

ྛɹᚸ࢘ (JU)VCTIJO ೥৽ଔೖࣾɻ ݱࡏ͸$"54ͱ͍͏νʔϜͰʮڝྠʹؔ͢Δ৽نαʔϏεʯͷJ04Λ୲౰ɻ ࣗݾ঺հ

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

3Y4XJGUͱ3FBDUJWF4XJGU

Slide 5

Slide 5 text

ݱࡏͷ৽نͰ3FBDUJWF4XJGU 461&3$)0*$&Ͱ3Y4XJGU 8IZ

Slide 6

Slide 6 text

ൺֱ

Slide 7

Slide 7 text

)PUͱ$PME

Slide 8

Slide 8 text

)PUͱ$PME )PU͸4VCTDSJCF͞Εͳͯ͘΋Πϕϯτ͕ྲྀΕΔ $PME͸4VCTDSJCF͞ΕΔ·ͰΠϕϯτ͕ྲྀΕͳ͍ )05 $0-% 46#4$3*#&

Slide 9

Slide 9 text

)PUͱ$PME )PU͸4VCTDSJCF͞ΕΔͱετϦʔϜ͕෼ذ͢Δ $PME͸4VCTDSJCF͞Εͨ෼ετϦʔϜ͕࡞ΒΕΔ

Slide 10

Slide 10 text

)PUͱ$PME $PME͸4VCTDSJCF͞Εͨ෼ετϦʔϜ͕࡞ΒΕΔ $0-% $0-% 46#4$3*#&

Slide 11

Slide 11 text

)PUͱ$PME $PME͸4VCTDSJCF͞Εͨ෼ετϦʔϜ͕࡞ΒΕΔ $0-% $0-% 46#4$3*#& 46#4$3*#&

Slide 12

Slide 12 text

)PUͱ$PME $PME͸4VCTDSJCF͞Εͨ෼ετϦʔϜ͕࡞ΒΕΔ $0-% $0-% 46#4$3*#& 46#4$3*#& $0-% $0-%

Slide 13

Slide 13 text

)PUͱ$PME )PU͸4VCTDSJCF͞ΕΔͱετϦʔϜ͕෼ذ͢Δ $0-% 46#4$3*#& )05

Slide 14

Slide 14 text

)PUͱ$PME )PU͸4VCTDSJCF͞ΕΔͱετϦʔϜ͕෼ذ͢Δ $0-% 46#4$3*#& )05 46#4$3*#&

Slide 15

Slide 15 text

)PUͱ$PME )PU͸4VCTDSJCF͞ΕΔͱετϦʔϜ͕෼ذ͢Δ $0-% 46#4$3*#& 46#4$3*#& )05

Slide 16

Slide 16 text

)PUͱ$PME $PME͸4VCTDSJCF͞Εͨ෼ετϦʔϜ͕࡞ΒΕΔ $0-% $0-% 46#4$3*#& 46#4$3*#& $0-% $0-%

Slide 17

Slide 17 text

)PUͱ$PME )PU͸4VCTDSJCF͞ΕΔͱετϦʔϜ͕෼ذ͢Δ $0-% 46#4$3*#& 46#4$3*#& )05

Slide 18

Slide 18 text

0CTFSWBCMF7BMVF )PU $PME 4JHOBM1SPEVDFS7BMVF &SSPS 4JHOBM7BMVF &SSPS 0CTFSWBCMF7BMVF )PUͱ$PME

Slide 19

Slide 19 text

&SSPS

Slide 20

Slide 20 text

0CTFSWBCMF7BMVF )PU $PME 4JHOBM1SPEVDFS7BMVF &SSPS 4JHOBM7BMVF &SSPS 0CTFSWBCMF7BMVF &SSPS

Slide 21

Slide 21 text

0CTFSWBCMF7BMVF )PU $PME 4JHOBM1SPEVDFS7BMVF &SSPS 4JHOBM7BMVF &SSPS 0CTFSWBCMF7BMVF &SSPS

Slide 22

Slide 22 text

&SSPS someObservable .subscribe(onError: { error in guard let error = error as? SomeError else { return } }) .disposed(by: disposeBag) ɾ3Y4XJGU

Slide 23

Slide 23 text

&SSPS let signalProducer = SignalProducer { innerObserver, disposable in innerObserver.send(value: 1) innerObserver.sendCompleted() } signalProducer .startWithResult { result in switch result { case let .success(value): print("value: \(value)") case let .failure(error): print("error: \(error)") } } ɾ3FBDUJWF4XJGU

Slide 24

Slide 24 text

&SSPS let signalProducer = SignalProducer { innerObserver, disposable in innerObserver.send(value: 1) innerObserver.sendCompleted() } signalProducer .startWithValue { result in print("value: \(value)”) } } ɾ3FBDUJWF4XJGU

Slide 25

Slide 25 text

#FIBWJPS3FMBZ.VUBCMF1SPQFSUZ

Slide 26

Slide 26 text

#FIBWJPS3FMBZ.VUBCMF1SPQFSUZ #FIBWJPS3FMBZ .VUBCMF1SPQFSUZ BehaviorRelay is a wrapper for `BehaviorSubject`. Unlike `BehaviorSubject` it can't terminate with error or completed. A mutable property of type `Value` that allows observation of its changes.

Slide 27

Slide 27 text

#FIBWJPS3FMBZ.VUBCMF1SPQFSUZ let behaviorRelay = BehaviorRelay(value: ["a"]) var mutableCopy = behaviorRelay.value mutableCopy.append(“b") behaviorRelay.accept(mutableCopy) ɾ#FIBWJPS3FMBZ let behaviorRelay = BehaviorRelay(value: ["a"]) behaviorRelay.value.append("b") ! ஋ͷΞΫηε͸WBMVFͱBDDFQU @FWFOU&MFNFOU Ͱߦ͏

Slide 28

Slide 28 text

#FIBWJPS3FMBZ.VUBCMF1SPQFSUZ public func modify(_ action: (inout Value) throws -> Result) rethrows -> Result { return try box.begin { storage in defer { observer.send(value: storage.value) } return try storage.modify(action) } } public func withValue(_ action: (Value) throws -> Result) rethrows -> Result { return try box.withValue { try action($0) } } ɾ.VUBCMF1SPQFSUZ

Slide 29

Slide 29 text

#FIBWJPS3FMBZ.VUBCMF1SPQFSUZ /// A reference counted box which holds a recursive lock and a value storage. /// /// The requirement of a `Value?` storage from composed properties prevents further /// implementation sharing with `MutableProperty`. private final class PropertyBox { private let lock: Lock.PthreadLock fileprivate var _value: Value fileprivate var isModifying = false internal var value: Value { lock.lock() defer { lock.unlock() } return _value } init(_ value: Value) { _value = value lock = Lock.PthreadLock(recursive: true) } func withValue(_ action: (Value) throws -> Result) rethrows -> Result { lock.lock() defer { lock.unlock() } return try action(_value) } func begin(_ action: (PropertyStorage) throws -> Result) rethrows -> Result { lock.lock() defer { lock.unlock() } return try action(PropertyStorage(self)) } } ɾ.VUBCMF1SPQFSUZ

Slide 30

Slide 30 text

ಈ޲

Slide 31

Slide 31 text

3Y4XJGU

Slide 32

Slide 32 text

3Y4XJGU 3PU8FJ– 4FQ •ɾCompatibility with Xcode 10.0 •ɾAdds new insert extension to collect and add multiple disposables to DisposeBag. •ɾAdds scan(into:accumulator:). •ɾAdds queuePriority parameter (defaults to .normal) to OperationQueueScheduler. •ɾPerformance enhancement reduces Bag dispatch inline code size by 12%. •ɾAdds customCaptureSubscriptionCallstack hook to allow custom subscription callstacks to be generated. •ɾRemove usage of Variable from Playground, Example projects and Tests. •ɾAdd XCTAssertRecordedElements to XCTest+Rx.

Slide 33

Slide 33 text

3Y4XJGU ɾ"EETOFXJOTFSUFYUFOTJPOUPDPMMFDUBOEBEENVMUJQMFEJTQPTBCMFTUP%JTQPTF#BH /// Convenience init allows a list of disposables to be gathered for disposal. public convenience init(disposing disposables: Disposable...) { self.init() self._disposables += disposables } /// Convenience init allows an array of disposables to be gathered for disposal. public convenience init(disposing disposables: [Disposable]) { self.init() self._disposables += disposables } /// Convenience function allows a list of disposables to be gathered for disposal. public func insert(_ disposables: Disposable...) { self.insert(disposables) } /// Convenience function allows an array of disposables to be gathered for disposal. public func insert(_ disposables: [Disposable]) { self._lock.lock(); defer { self._lock.unlock() } if self._isDisposed { disposables.forEach { $0.dispose() } } else { self._disposables += disposables } }

Slide 34

Slide 34 text

3Y4XJGU func testDisposeBagVaradicInsert() { let disposable1 = TestDisposable() let disposable2 = TestDisposable() var disposeBag: DisposeBag? = DisposeBag() disposeBag?.insert(disposable1, disposable2) XCTAssert(disposable1.count == 0) XCTAssert(disposable2.count == 0) disposeBag = nil XCTAssert(disposable1.count == 1) XCTAssert(disposable2.count == 1) } func testDisposeBagVaradicInsertArray() { let disposable1 = TestDisposable() let disposable2 = TestDisposable() var disposeBag: DisposeBag? = DisposeBag() disposeBag?.insert([disposable1, disposable2]) XCTAssert(disposable1.count == 0) XCTAssert(disposable2.count == 0) disposeBag = nil XCTAssert(disposable1.count == 1) XCTAssert(disposable2.count == 1) } ɾ"EETOFXJOTFSUFYUFOTJPOUPDPMMFDUBOEBEENVMUJQMFEJTQPTBCMFTUP%JTQPTF#BH

Slide 35

Slide 35 text

3Y4XJGU ɾ"EETqueuePriorityQBSBNFUFS EFGBVMUTUP.normal UPOperationQueueScheduler public let queuePriority: Operation.QueuePriority let highPriority = OperationQueueScheduler( operationQueue: operationQueue, queuePriority: .high ) let lowPriority = OperationQueueScheduler( operationQueue: operationQueue, queuePriority: .low )

Slide 36

Slide 36 text

3Y4XJGU "UPNJD /PW •This relase introduces new framework RxAtomic that enables using C11 atomic primities •in RxSwift as a replacement for deprecated OSAtomic* functions.
 Carthage users will probably need to include this framework manually. •ɾUpdates deprecated OSAtomic* primitives to use C11 atomic primitives. •ɾAdds Event, SingleEvent, MaybeEvent and Recorded conditional conformance •ɹto Equatablewhere their Element is equatable on RXTest for clients that are using Swift >= 4.1. •ɾAdds string to NSTextView. •ɾConsolidates per platform frameworks to multi-platform frameworks. •ɾXcode 10.1 compatible. •

Slide 37

Slide 37 text

3Y4XJGU This relase introduces new framework RxAtomic

Slide 38

Slide 38 text

3Y4XJGU /*! @header * These are deprecated legacy interfaces for atomic operations. * The C11 interfaces in resp. C++11 interfaces in * should be used instead. * * Define OSATOMIC_USE_INLINED=1 to get inline implementations of these * interfaces in terms of the resp. primitives. * This is intended as a transition convenience, direct use of those primitives * is preferred. */ ɾOSAtomic

Slide 39

Slide 39 text

3FBDUJWF4XJGU

Slide 40

Slide 40 text

3FBDUJWF4XJGU ɾXcode 10 Support ɾOperators ɾChanges: <~ Bindings ɾChanges: Conditional Conformance ɾInteroperability ɾMiscellaneous ɾ4.0.0

Slide 41

Slide 41 text

3FBDUJWF4XJGU ɾ0QFSBUPST

Slide 42

Slide 42 text

3FBDUJWF4XJGU 1.<~ bindings now works with optional left-hand-side operands. 2.(#642, kudos to @andersio and @Ankit-Aggarwal) ɾ$IBOHFT<~#JOEJOHT let nilTarget: BindingTarget? = nil // This is now a valid binding. Previously required manual // unwrapping in ReactiveSwift 3.x. nilTarget <~ notifications.map { $0.count }

Slide 43

Slide 43 text

3FBDUJWF4XJGU public enum Result { case success(Success) case failure(Failure) } [WIP] Removing Result in favor of Swift.Result #702 /// A protocol that can be used to constrain associated types as `Result`. public protocol ResultProtocol { associatedtype Success associatedtype Failure: Swift.Error init(success: Success) init(failure: Failure) var result: Result { get } } 4XJGUBOE3FTVMUJO4UBOEBSE-JCSBSZ

Slide 44

Slide 44 text

3FBDUJWF4XJGU ɾ1SPNJTFESBGU

Slide 45

Slide 45 text

3Y4XJGU3FBDUJWF4XJGU

Slide 46

Slide 46 text

5IBOL:PV