diff --git a/.gitignore b/.gitignore index 9767142..5b3f37c 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ Carthage/Build fastlane/report.xml fastlane/screenshots + +# SPM +.swiftpm/ diff --git a/.travis.yml b/.travis.yml index a6dc818..569efa6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ env: - LC_CTYPE=en_US.UTF-8 - XCPROJ="-workspace RxAutomaton.xcworkspace -scheme RxAutomaton" -osx_image: xcode10.2 +osx_image: xcode12.5 matrix: include: diff --git a/Cartfile b/Cartfile index 6a8bfd6..bcb3591 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "ReactiveX/RxSwift" ~> 5.0 +github "ReactiveX/RxSwift" ~> 6.0 diff --git a/Cartfile.resolved b/Cartfile.resolved index 90b5a70..4d9d8ea 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,5 +1,5 @@ -github "Quick/Nimble" "v8.0.2" -github "Quick/Quick" "v2.1.0" -github "ReactiveX/RxSwift" "5.0.1" +github "Quick/Nimble" "v9.2.0" +github "Quick/Quick" "v4.0.0" +github "ReactiveX/RxSwift" "6.2.0" github "mrackwitz/xcconfigs" "3.0" github "shu223/Pulsator" "0.4.2" diff --git a/Carthage/Checkouts/Nimble b/Carthage/Checkouts/Nimble index f865764..af1730d 160000 --- a/Carthage/Checkouts/Nimble +++ b/Carthage/Checkouts/Nimble @@ -1 +1 @@ -Subproject commit f8657642dfdec9973efc79cc68bcef43a653a2bc +Subproject commit af1730dde4e6c0d45bf01b99f8a41713ce536790 diff --git a/Carthage/Checkouts/Quick b/Carthage/Checkouts/Quick index 94df9b4..bd86ca0 160000 --- a/Carthage/Checkouts/Quick +++ b/Carthage/Checkouts/Quick @@ -1 +1 @@ -Subproject commit 94df9b449508344667e5afc7e80f8bcbff1e4c37 +Subproject commit bd86ca0141e3cfb333546de5a11ede63f0c4a0e6 diff --git a/Carthage/Checkouts/RxSwift b/Carthage/Checkouts/RxSwift index b3e888b..7c17a6c 160000 --- a/Carthage/Checkouts/RxSwift +++ b/Carthage/Checkouts/RxSwift @@ -1 +1 @@ -Subproject commit b3e888b4972d9bc76495dd74d30a8c7fad4b9395 +Subproject commit 7c17a6ccca06b5c107cfa4284e634562ddaf5951 diff --git a/Package.resolved b/Package.resolved index 4c615b1..4c541df 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,31 +1,13 @@ { "object": { "pins": [ - { - "package": "Nimble", - "repositoryURL": "https://github.com/Quick/Nimble.git", - "state": { - "branch": null, - "revision": "f8657642dfdec9973efc79cc68bcef43a653a2bc", - "version": "8.0.2" - } - }, - { - "package": "Quick", - "repositoryURL": "https://github.com/Quick/Quick.git", - "state": { - "branch": null, - "revision": "94df9b449508344667e5afc7e80f8bcbff1e4c37", - "version": "2.1.0" - } - }, { "package": "RxSwift", "repositoryURL": "https://github.com/ReactiveX/RxSwift.git", "state": { "branch": null, - "revision": "b3e888b4972d9bc76495dd74d30a8c7fad4b9395", - "version": "5.0.1" + "revision": "7c17a6ccca06b5c107cfa4284e634562ddaf5951", + "version": "6.2.0" } } ] diff --git a/Package.swift b/Package.swift index bed6627..6ce5c45 100644 --- a/Package.swift +++ b/Package.swift @@ -11,12 +11,12 @@ let package = Package( targets: ["RxAutomaton"]), ], dependencies: [ - .package(url: "https://github.com/ReactiveX/RxSwift.git", from: "5.0.0"), + .package(url: "https://github.com/ReactiveX/RxSwift.git", from: "6.2.0"), ], targets: [ .target( name: "RxAutomaton", - dependencies: ["RxSwift", "RxCocoa"], + dependencies: ["RxSwift", "RxCocoa", "RxRelay"], path: "Sources"), ] ) @@ -31,8 +31,8 @@ if ProcessInfo.processInfo.environment.keys.contains("RXAUTOMATON_SPM_TEST") { package.dependencies.append( contentsOf: [ - .package(url: "https://github.com/Quick/Quick.git", from: "2.1.0"), - .package(url: "https://github.com/Quick/Nimble.git", from: "8.0.0"), + .package(url: "https://github.com/Quick/Quick.git", from: "4.0.0"), + .package(url: "https://github.com/Quick/Nimble.git", from: "9.2.0"), ] ) } diff --git a/RxAutomaton.podspec b/RxAutomaton.podspec index 7cbf208..2af2c20 100644 --- a/RxAutomaton.podspec +++ b/RxAutomaton.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |s| s.name = "RxAutomaton" - s.version = "0.4.0" + s.version = "0.5.0" s.summary = "RxSwift + State Machine, inspired by Redux and Elm." s.homepage = "https://github.com/inamiy/RxAutomaton" s.license = { :type => "MIT", :file => "LICENSE" } s.author = { "Yasuhiro Inami" => "inamiy@gmail.com" } - s.ios.deployment_target = "8.0" + s.ios.deployment_target = "9.0" s.osx.deployment_target = "10.10" s.watchos.deployment_target = "3.0" s.tvos.deployment_target = "9.0" @@ -14,5 +14,6 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/inamiy/RxAutomaton.git", :tag => "#{s.version}" } s.source_files = "Sources/**/*.swift" - s.dependency "RxSwift", "~> 5.0" + s.dependency "RxSwift", "~> 6.0" + s.dependency "RxRelay", "~> 6.0" end diff --git a/Sources/Automaton.swift b/Sources/Automaton.swift index 6393764..b896073 100644 --- a/Sources/Automaton.swift +++ b/Sources/Automaton.swift @@ -7,6 +7,7 @@ // import RxSwift +import RxRelay // // Terminology: @@ -32,7 +33,7 @@ public final class Automaton /// Current state. /// - Todo: Use RxProperty https://github.com/inamiy/RxProperty - public let state: Variable + public let state: BehaviorRelay private let _replyObserver: AnyObserver> @@ -62,7 +63,7 @@ public final class Automaton /// public init(state initialState: State, input inputSignal: Observable, mapping: @escaping EffectMapping, strategy: FlattenStrategy = .merge) { - let stateProperty = Variable(initialState) + let stateProperty = BehaviorRelay(value: initialState) self.state = stateProperty // TODO: AnyProperty(stateProperty) let p = PublishSubject>() @@ -153,11 +154,11 @@ extension Observable { // No idea why this is not in RxSwift but RxCocoa... extension ObservableType { - fileprivate func bindTo(_ variable: Variable) -> Disposable { + fileprivate func bindTo(_ variable: BehaviorRelay) -> Disposable { return subscribe { e in switch e { case let .next(element): - variable.value = element + variable.accept(element) case let .error(error): let error = "Binding error to variable: \(error)" #if DEBUG diff --git a/Sources/RxSwift+Pipe.swift b/Sources/RxSwift+Pipe.swift index 2a6d397..3208cf5 100644 --- a/Sources/RxSwift+Pipe.swift +++ b/Sources/RxSwift+Pipe.swift @@ -11,8 +11,8 @@ import RxSwift extension ObservableType { /// From ReactiveCocoa. - public static func pipe() -> (Observable, AnyObserver) { - let p = PublishSubject() + public static func pipe() -> (Observable, AnyObserver) { + let p = PublishSubject() return (p.asObservable(), AnyObserver(eventHandler: p.asObserver().on)) } diff --git a/Sources/RxSwift+Then.swift b/Sources/RxSwift+Then.swift index c56b667..e26eb87 100644 --- a/Sources/RxSwift+Then.swift +++ b/Sources/RxSwift+Then.swift @@ -12,7 +12,7 @@ extension ObservableType { /// From ReactiveCocoa (naive implementation). public func then(_ second: O) -> Observable - where O.E == E2 + where O.Element == E2 { return self .filter { _ in false } diff --git a/Tests/RxAutomatonTests/EffectMappingLatestSpec.swift b/Tests/RxAutomatonTests/EffectMappingLatestSpec.swift index f8d5be2..a8e8375 100644 --- a/Tests/RxAutomatonTests/EffectMappingLatestSpec.swift +++ b/Tests/RxAutomatonTests/EffectMappingLatestSpec.swift @@ -33,12 +33,12 @@ class EffectMappingLatestSpec: QuickSpec /// Sends `.loginOK` after delay, simulating async work during `.loggingIn`. let loginOKProducer = Observable.just(AuthInput.loginOK) - .delay(1, onScheduler: testScheduler) + .delay(.seconds(1), onScheduler: testScheduler) /// Sends `.logoutOK` after delay, simulating async work during `.loggingOut`. let logoutOKProducer = Observable.just(AuthInput.logoutOK) - .delay(1, onScheduler: testScheduler) + .delay(.seconds(1), onScheduler: testScheduler) let mappings: [Automaton.EffectMapping] = [ .login | .loggedOut => .loggingIn | loginOKProducer, diff --git a/Tests/RxAutomatonTests/EffectMappingSpec.swift b/Tests/RxAutomatonTests/EffectMappingSpec.swift index 2d2be90..2edbdd3 100644 --- a/Tests/RxAutomatonTests/EffectMappingSpec.swift +++ b/Tests/RxAutomatonTests/EffectMappingSpec.swift @@ -34,12 +34,12 @@ class EffectMappingSpec: QuickSpec /// Sends `.loginOK` after delay, simulating async work during `.loggingIn`. let loginOKProducer = Observable.just(AuthInput.loginOK) - .delay(1, onScheduler: testScheduler) + .delay(.seconds(1), onScheduler: testScheduler) /// Sends `.logoutOK` after delay, simulating async work during `.loggingOut`. let logoutOKProducer = Observable.just(AuthInput.logoutOK) - .delay(1, onScheduler: testScheduler) + .delay(.seconds(1), onScheduler: testScheduler) let mappings: [Automaton.EffectMapping] = [ .login | .loggedOut => .loggingIn | loginOKProducer, @@ -128,12 +128,12 @@ class EffectMappingSpec: QuickSpec /// Sends `.loginOK` after delay, simulating async work during `.loggingIn`. let loginOKProducer = Observable.just(AuthInput.loginOK) - .delay(1, onScheduler: testScheduler) + .delay(.seconds(1), onScheduler: testScheduler) /// Sends `.logoutOK` after delay, simulating async work during `.loggingOut`. let logoutOKProducer = Observable.just(AuthInput.logoutOK) - .delay(1, onScheduler: testScheduler) + .delay(.seconds(1), onScheduler: testScheduler) let mapping: EffectMapping = { fromState, input in switch (fromState, input) { diff --git a/Tests/RxAutomatonTests/Fixtures/ToRACHelper.swift b/Tests/RxAutomatonTests/Fixtures/ToRACHelper.swift index 870990a..10de505 100644 --- a/Tests/RxAutomatonTests/Fixtures/ToRACHelper.swift +++ b/Tests/RxAutomatonTests/Fixtures/ToRACHelper.swift @@ -12,7 +12,7 @@ import RxSwift // R-A-C! R-A-C! extension ObservableType { - func delay(_ time: TimeInterval, onScheduler scheduler: SchedulerType) -> Observable { + func delay(_ time: DispatchTimeInterval, onScheduler scheduler: SchedulerType) -> Observable { return self.flatMap { element in return Observable.interval(time, scheduler: scheduler) .map { _ in element } @@ -23,18 +23,18 @@ extension ObservableType { extension ObservableType { @discardableResult - func observeValues(_ next: @escaping (E) -> Void) -> Disposable { + func observeValues(_ next: @escaping (Element) -> Void) -> Disposable { return self.subscribe(onNext: next) } @discardableResult - func observe(_ observer: @escaping (Event) -> Void) -> Disposable { + func observe(_ observer: @escaping (Event) -> Void) -> Disposable { return self.subscribe(AnyObserver(eventHandler: observer)) } } extension ObserverType { - func send(next value: E) { + func send(next value: Element) { self.onNext(value) } diff --git a/Tests/RxAutomatonTests/TerminatingSpec.swift b/Tests/RxAutomatonTests/TerminatingSpec.swift index 997294d..60d7ba3 100644 --- a/Tests/RxAutomatonTests/TerminatingSpec.swift +++ b/Tests/RxAutomatonTests/TerminatingSpec.swift @@ -39,8 +39,8 @@ class TerminatingSpec: QuickSpec let sendInput1And2AfterDelay: Observable = Observable.concat([ - Observable.just(.input1).delay(1, onScheduler: testScheduler), - Observable.just(.input2).delay(1, onScheduler: testScheduler), + Observable.just(.input1).delay(.seconds(1), onScheduler: testScheduler), + Observable.just(.input2).delay(.seconds(1), onScheduler: testScheduler), ]) let mappings: [Automaton.EffectMapping] = [