From 10a3f4da96183224ebd42b0644cbb7f489ed1b23 Mon Sep 17 00:00:00 2001 From: Ibrahim Koteish Date: Thu, 5 Mar 2020 17:34:48 +0100 Subject: [PATCH 1/5] Add Deferred struct like the one in combine style --- ReactiveKit.xcodeproj/project.pbxproj | 10 ++++++ Sources/Deferred.swift | 50 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 Sources/Deferred.swift diff --git a/ReactiveKit.xcodeproj/project.pbxproj b/ReactiveKit.xcodeproj/project.pbxproj index 37d0ca7..44cb08d 100644 --- a/ReactiveKit.xcodeproj/project.pbxproj +++ b/ReactiveKit.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 08788B2E2411609D0011CB5E /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B2D2411609D0011CB5E /* Deferred.swift */; }; + 08788B2F2411609D0011CB5E /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B2D2411609D0011CB5E /* Deferred.swift */; }; + 08788B302411609D0011CB5E /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B2D2411609D0011CB5E /* Deferred.swift */; }; + 08788B312411609D0011CB5E /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B2D2411609D0011CB5E /* Deferred.swift */; }; 08B5D54E23A68647000AE983 /* PublishedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B5D54C23A68618000AE983 /* PublishedTests.swift */; }; 16C33B841BEFBAC900A0DBE0 /* ReactiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = ECBCCDD31BEB6B9A00723476 /* ReactiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16C33B851BEFBAC900A0DBE0 /* ReactiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = ECBCCDD31BEB6B9A00723476 /* ReactiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -192,6 +196,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 08788B2D2411609D0011CB5E /* Deferred.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Deferred.swift; sourceTree = ""; }; 08B5D54C23A68618000AE983 /* PublishedTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublishedTests.swift; sourceTree = ""; }; 162CB7461CB451D200FB6375 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 1671707E1BF4F62A001786CE /* ReactiveKit.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = ReactiveKit.podspec; sourceTree = SOURCE_ROOT; }; @@ -320,6 +325,7 @@ EC48D308224FB5C400284EA0 /* SignalProtocol+Result.swift */, EC48D2F9224FB5C400284EA0 /* SignalProtocol+Optional.swift */, EC48D30A224FB5C400284EA0 /* SignalProtocol+Sequence.swift */, + 08788B2D2411609D0011CB5E /* Deferred.swift */, EC48D301224FB5C400284EA0 /* Subjects.swift */, EC48D302224FB5C400284EA0 /* Connectable.swift */, EC48D2F5224FB5C400284EA0 /* Property.swift */, @@ -660,6 +666,7 @@ EC7717ED23BE33650036A609 /* Sink.swift in Sources */, EC48D36A224FB5C400284EA0 /* SignalProtocol+Result.swift in Sources */, ECDFDCB322BD7E9500B85C5E /* Completion.swift in Sources */, + 08788B2F2411609D0011CB5E /* Deferred.swift in Sources */, EC48D32A224FB5C400284EA0 /* SignalProtocol+Threading.swift in Sources */, EC48D366224FB5C400284EA0 /* SignalProtocol+Transforming.swift in Sources */, EC48D346224FB5C400284EA0 /* Bindable.swift in Sources */, @@ -707,6 +714,7 @@ EC7717EE23BE33650036A609 /* Sink.swift in Sources */, EC48D36B224FB5C400284EA0 /* SignalProtocol+Result.swift in Sources */, ECDFDCB422BD7E9500B85C5E /* Completion.swift in Sources */, + 08788B302411609D0011CB5E /* Deferred.swift in Sources */, EC48D32B224FB5C400284EA0 /* SignalProtocol+Threading.swift in Sources */, EC48D367224FB5C400284EA0 /* SignalProtocol+Transforming.swift in Sources */, EC48D347224FB5C400284EA0 /* Bindable.swift in Sources */, @@ -754,6 +762,7 @@ EC7717EF23BE33650036A609 /* Sink.swift in Sources */, EC48D36C224FB5C400284EA0 /* SignalProtocol+Result.swift in Sources */, ECDFDCB522BD7E9500B85C5E /* Completion.swift in Sources */, + 08788B312411609D0011CB5E /* Deferred.swift in Sources */, EC48D32C224FB5C400284EA0 /* SignalProtocol+Threading.swift in Sources */, EC48D368224FB5C400284EA0 /* SignalProtocol+Transforming.swift in Sources */, EC48D348224FB5C400284EA0 /* Bindable.swift in Sources */, @@ -801,6 +810,7 @@ EC7717EC23BE33650036A609 /* Sink.swift in Sources */, EC48D369224FB5C400284EA0 /* SignalProtocol+Result.swift in Sources */, ECDFDCB222BD7E9500B85C5E /* Completion.swift in Sources */, + 08788B2E2411609D0011CB5E /* Deferred.swift in Sources */, EC48D329224FB5C400284EA0 /* SignalProtocol+Threading.swift in Sources */, EC48D365224FB5C400284EA0 /* SignalProtocol+Transforming.swift in Sources */, EC48D345224FB5C400284EA0 /* Bindable.swift in Sources */, diff --git a/Sources/Deferred.swift b/Sources/Deferred.swift new file mode 100644 index 0000000..59133e4 --- /dev/null +++ b/Sources/Deferred.swift @@ -0,0 +1,50 @@ +// +// Deferred.swift +// GlovoCourier +// +// Created by Ibrahim Koteish on 01/12/2019. +// Copyright © 2019 Glovo. All rights reserved. +// + +import Foundation + +/// A signal that awaits subscription before running the supplied closure +/// to create a signal for the new subscriber. +public struct Deferred: SignalProtocol { + + /// The kind of values published by this signal. + public typealias Element = DeferredSignal.Element + + /// The kind of errors this signal might publish. + /// + /// Use `Never` if this `signal` does not publish errors. + public typealias Error = DeferredSignal.Error + + /// The closure to execute when it receives a subscription. + /// + /// The signal returned by this closure immediately + /// receives the incoming subscription. + public let signalFactory: () -> DeferredSignal + + /// Creates a deferred signal. + /// + /// - Parameter signalFactory: The closure to execute + /// when calling `observe(with:)`. + public init(signalFactory: @escaping () -> DeferredSignal) { + self.signalFactory = signalFactory + } + + /// This function is called to attach the specified `Observer` + /// to this `Signal` by `observe(with:)` + /// + /// - Parameters: + /// - observer: The observer to attach to this `Signal`. + /// once attached it can begin to receive values. + public func observe( + with observer: @escaping (Signal.Event) -> Void) + -> Disposable + { + let deferredSignal = signalFactory() + return deferredSignal.observe(with: observer) + } +} From 8bef971b8d31d77f815e835ea9daf4833a6cf260 Mon Sep 17 00:00:00 2001 From: Srdan Rasic Date: Thu, 5 Mar 2020 17:54:38 +0100 Subject: [PATCH 2/5] Bump --- ReactiveKit.podspec | 4 ++-- ReactiveKit.xcodeproj/project.pbxproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ReactiveKit.podspec b/ReactiveKit.podspec index 2039692..d5c4ca1 100644 --- a/ReactiveKit.podspec +++ b/ReactiveKit.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |s| s.name = "ReactiveKit" - s.version = "3.16.2" + s.version = "3.16.3" s.summary = "A Swift Reactive Programming Framework" s.description = "ReactiveKit is a Swift framework for reactive and functional reactive programming." s.homepage = "https://github.com/DeclarativeHub/ReactiveKit" s.license = 'MIT' s.author = { "Srdan Rasic" => "srdan.rasic@gmail.com" } - s.source = { :git => "https://github.com/DeclarativeHub/ReactiveKit.git", :tag => "v3.16.2" } + s.source = { :git => "https://github.com/DeclarativeHub/ReactiveKit.git", :tag => "v3.16.3" } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.11' diff --git a/ReactiveKit.xcodeproj/project.pbxproj b/ReactiveKit.xcodeproj/project.pbxproj index 44cb08d..3596b0a 100644 --- a/ReactiveKit.xcodeproj/project.pbxproj +++ b/ReactiveKit.xcodeproj/project.pbxproj @@ -1051,7 +1051,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 3.16.2; + MARKETING_VERSION = 3.16.3; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -1106,7 +1106,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 3.16.2; + MARKETING_VERSION = 3.16.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_VERSION = 4.0; From 06c7ef193d78d027d56e1bb3ce5627492c4e8fc5 Mon Sep 17 00:00:00 2001 From: Ibrahim Koteish Date: Fri, 6 Mar 2020 00:55:27 +0100 Subject: [PATCH 3/5] Add Combine style empty struct --- ReactiveKit.xcodeproj/project.pbxproj | 10 +++++ Sources/Empty.swift | 63 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 Sources/Empty.swift diff --git a/ReactiveKit.xcodeproj/project.pbxproj b/ReactiveKit.xcodeproj/project.pbxproj index 3596b0a..1bb3fee 100644 --- a/ReactiveKit.xcodeproj/project.pbxproj +++ b/ReactiveKit.xcodeproj/project.pbxproj @@ -11,6 +11,10 @@ 08788B2F2411609D0011CB5E /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B2D2411609D0011CB5E /* Deferred.swift */; }; 08788B302411609D0011CB5E /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B2D2411609D0011CB5E /* Deferred.swift */; }; 08788B312411609D0011CB5E /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B2D2411609D0011CB5E /* Deferred.swift */; }; + 08788B392411C5D00011CB5E /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B382411C5D00011CB5E /* Empty.swift */; }; + 08788B3A2411C5F30011CB5E /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B382411C5D00011CB5E /* Empty.swift */; }; + 08788B3B2411C5F30011CB5E /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B382411C5D00011CB5E /* Empty.swift */; }; + 08788B3C2411C5F40011CB5E /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08788B382411C5D00011CB5E /* Empty.swift */; }; 08B5D54E23A68647000AE983 /* PublishedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B5D54C23A68618000AE983 /* PublishedTests.swift */; }; 16C33B841BEFBAC900A0DBE0 /* ReactiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = ECBCCDD31BEB6B9A00723476 /* ReactiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16C33B851BEFBAC900A0DBE0 /* ReactiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = ECBCCDD31BEB6B9A00723476 /* ReactiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -197,6 +201,7 @@ /* Begin PBXFileReference section */ 08788B2D2411609D0011CB5E /* Deferred.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Deferred.swift; sourceTree = ""; }; + 08788B382411C5D00011CB5E /* Empty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Empty.swift; sourceTree = ""; }; 08B5D54C23A68618000AE983 /* PublishedTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublishedTests.swift; sourceTree = ""; }; 162CB7461CB451D200FB6375 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 1671707E1BF4F62A001786CE /* ReactiveKit.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = ReactiveKit.podspec; sourceTree = SOURCE_ROOT; }; @@ -326,6 +331,7 @@ EC48D2F9224FB5C400284EA0 /* SignalProtocol+Optional.swift */, EC48D30A224FB5C400284EA0 /* SignalProtocol+Sequence.swift */, 08788B2D2411609D0011CB5E /* Deferred.swift */, + 08788B382411C5D00011CB5E /* Empty.swift */, EC48D301224FB5C400284EA0 /* Subjects.swift */, EC48D302224FB5C400284EA0 /* Connectable.swift */, EC48D2F5224FB5C400284EA0 /* Property.swift */, @@ -653,6 +659,7 @@ EC48D356224FB5C400284EA0 /* Reactive.swift in Sources */, EC75487F2351E2AC002D869C /* Scheduler.swift in Sources */, EC912A6E23BCB00500701259 /* Subscription.swift in Sources */, + 08788B3A2411C5F30011CB5E /* Empty.swift in Sources */, EC48D35A224FB5C400284EA0 /* LoadingSignal.swift in Sources */, EC48D376224FB5C400284EA0 /* Signal.swift in Sources */, EC48D32E224FB5C400284EA0 /* SignalProtocol+Optional.swift in Sources */, @@ -701,6 +708,7 @@ EC48D357224FB5C400284EA0 /* Reactive.swift in Sources */, EC7548802351E2AC002D869C /* Scheduler.swift in Sources */, EC912A6F23BCB00500701259 /* Subscription.swift in Sources */, + 08788B3B2411C5F30011CB5E /* Empty.swift in Sources */, EC48D35B224FB5C400284EA0 /* LoadingSignal.swift in Sources */, EC48D377224FB5C400284EA0 /* Signal.swift in Sources */, EC48D32F224FB5C400284EA0 /* SignalProtocol+Optional.swift in Sources */, @@ -749,6 +757,7 @@ EC48D358224FB5C400284EA0 /* Reactive.swift in Sources */, EC7548812351E2AC002D869C /* Scheduler.swift in Sources */, EC912A7023BCB00500701259 /* Subscription.swift in Sources */, + 08788B3C2411C5F40011CB5E /* Empty.swift in Sources */, EC48D35C224FB5C400284EA0 /* LoadingSignal.swift in Sources */, EC48D378224FB5C400284EA0 /* Signal.swift in Sources */, EC48D330224FB5C400284EA0 /* SignalProtocol+Optional.swift in Sources */, @@ -797,6 +806,7 @@ EC48D355224FB5C400284EA0 /* Reactive.swift in Sources */, EC75487E2351E2AC002D869C /* Scheduler.swift in Sources */, EC912A6D23BCB00500701259 /* Subscription.swift in Sources */, + 08788B392411C5D00011CB5E /* Empty.swift in Sources */, EC48D359224FB5C400284EA0 /* LoadingSignal.swift in Sources */, EC48D375224FB5C400284EA0 /* Signal.swift in Sources */, EC48D32D224FB5C400284EA0 /* SignalProtocol+Optional.swift in Sources */, diff --git a/Sources/Empty.swift b/Sources/Empty.swift new file mode 100644 index 0000000..0627965 --- /dev/null +++ b/Sources/Empty.swift @@ -0,0 +1,63 @@ +// +// Empty.swift +// ReactiveKit-iOS +// +// Created by Ibrahim Koteish on 06/03/2020. +// Copyright © 2020 DeclarativeHub. All rights reserved. +// + +import Foundation + +/// A signal that never publishes any values, and optionally finishes immediately. +/// +/// You can create a ”Never” signal — one which never sends values and never +/// finishes or fails — with the initializer `Empty(completeImmediately: false)`. +public struct Empty: SignalProtocol, Equatable { + + /// The kind of values published by this signal. + public typealias Element = Element + + /// The kind of errors this signal might publish. + /// + /// Use `Never` if this `signal` does not publish errors. + public typealias Error = Error + + /// Creates an empty signal. + /// + /// - Parameter completeImmediately: A Boolean value that indicates whether + /// the signal should immediately finish. + public init(completeImmediately: Bool = true) { + self.completeImmediately = completeImmediately + } + + /// Creates an empty signal with the given completion behavior and output and + /// failure types. + /// + /// Use this initializer to connect the empty signal to observers or other + /// signals that have specific output and failure types. + /// - Parameters: + /// - completeImmediately: A Boolean value that indicates whether the signal + /// should immediately finish. + /// - outputType: The output type exposed by this signal. + /// - failureType: The failure type exposed by this signal. + public init(completeImmediately: Bool = true, + outputType: Element.Type, + failureType: Error.Type) { + self.init(completeImmediately: completeImmediately) + } + + /// A Boolean value that indicates whether the signal immediately sends + /// a completion. + /// + /// If `true`, the signal finishes immediately after sending an event + /// to the observer. If `false`, it never completes. + public let completeImmediately: Bool + + public func observe(with observer: @escaping (Signal.Event) -> Void) -> Disposable { + + if completeImmediately { + return Signal.completed().observe(with: observer) + } + return Signal.never().observe(with: observer) + } +} From d3bf871bf3bac96c28461c3d563c47757034f7b6 Mon Sep 17 00:00:00 2001 From: Srdan Rasic Date: Fri, 6 Mar 2020 21:25:41 +0100 Subject: [PATCH 4/5] Move publishers into a folder --- ReactiveKit.xcodeproj/project.pbxproj | 12 ++++++++++-- Sources/{ => Publishers}/Deferred.swift | 0 Sources/{ => Publishers}/Empty.swift | 0 3 files changed, 10 insertions(+), 2 deletions(-) rename Sources/{ => Publishers}/Deferred.swift (100%) rename Sources/{ => Publishers}/Empty.swift (100%) diff --git a/ReactiveKit.xcodeproj/project.pbxproj b/ReactiveKit.xcodeproj/project.pbxproj index 1bb3fee..0a6c847 100644 --- a/ReactiveKit.xcodeproj/project.pbxproj +++ b/ReactiveKit.xcodeproj/project.pbxproj @@ -306,6 +306,7 @@ EC48D2F0224FB5C400284EA0 /* Sources */ = { isa = PBXGroup; children = ( + EC4A95E72412E90A00362F60 /* Publishers */, EC7717E923BE23440036A609 /* Subscribers */, EC75487D2351E2AC002D869C /* Scheduler.swift */, EC912A5D23BCAD2600701259 /* Subscriber.swift */, @@ -330,8 +331,6 @@ EC48D308224FB5C400284EA0 /* SignalProtocol+Result.swift */, EC48D2F9224FB5C400284EA0 /* SignalProtocol+Optional.swift */, EC48D30A224FB5C400284EA0 /* SignalProtocol+Sequence.swift */, - 08788B2D2411609D0011CB5E /* Deferred.swift */, - 08788B382411C5D00011CB5E /* Empty.swift */, EC48D301224FB5C400284EA0 /* Subjects.swift */, EC48D302224FB5C400284EA0 /* Connectable.swift */, EC48D2F5224FB5C400284EA0 /* Property.swift */, @@ -372,6 +371,15 @@ path = ReactiveKitTests; sourceTree = ""; }; + EC4A95E72412E90A00362F60 /* Publishers */ = { + isa = PBXGroup; + children = ( + 08788B2D2411609D0011CB5E /* Deferred.swift */, + 08788B382411C5D00011CB5E /* Empty.swift */, + ); + path = Publishers; + sourceTree = ""; + }; EC7717E923BE23440036A609 /* Subscribers */ = { isa = PBXGroup; children = ( diff --git a/Sources/Deferred.swift b/Sources/Publishers/Deferred.swift similarity index 100% rename from Sources/Deferred.swift rename to Sources/Publishers/Deferred.swift diff --git a/Sources/Empty.swift b/Sources/Publishers/Empty.swift similarity index 100% rename from Sources/Empty.swift rename to Sources/Publishers/Empty.swift From 0e553b1af3bc3b6932fa2b0207b11244ba69c1db Mon Sep 17 00:00:00 2001 From: Srdan Rasic Date: Fri, 6 Mar 2020 21:26:48 +0100 Subject: [PATCH 5/5] Bump --- ReactiveKit.podspec | 4 ++-- ReactiveKit.xcodeproj/project.pbxproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ReactiveKit.podspec b/ReactiveKit.podspec index d5c4ca1..468d7bc 100644 --- a/ReactiveKit.podspec +++ b/ReactiveKit.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |s| s.name = "ReactiveKit" - s.version = "3.16.3" + s.version = "3.16.4" s.summary = "A Swift Reactive Programming Framework" s.description = "ReactiveKit is a Swift framework for reactive and functional reactive programming." s.homepage = "https://github.com/DeclarativeHub/ReactiveKit" s.license = 'MIT' s.author = { "Srdan Rasic" => "srdan.rasic@gmail.com" } - s.source = { :git => "https://github.com/DeclarativeHub/ReactiveKit.git", :tag => "v3.16.3" } + s.source = { :git => "https://github.com/DeclarativeHub/ReactiveKit.git", :tag => "v3.16.4" } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.11' diff --git a/ReactiveKit.xcodeproj/project.pbxproj b/ReactiveKit.xcodeproj/project.pbxproj index 0a6c847..c81c1d6 100644 --- a/ReactiveKit.xcodeproj/project.pbxproj +++ b/ReactiveKit.xcodeproj/project.pbxproj @@ -1069,7 +1069,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 3.16.3; + MARKETING_VERSION = 3.16.4; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -1124,7 +1124,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.10; - MARKETING_VERSION = 3.16.3; + MARKETING_VERSION = 3.16.4; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_VERSION = 4.0;