Swiftpack.co - Package - broadwaylamb/OpenCombine


CircleCI codecov Language Platform Cocoapods

Open-source implementation of Apple's Combine framework for processing values over time.

The main goal of this project is to provide a compatible, reliable and efficient implementation which can be used on Apple's operating systems before macOS 10.15 and iOS 13, as well as Linux and Windows.

The project is in early development.


OpenCombine contains three public targets: OpenCombine, OpenCombineFoundation and OpenCombineDispatch (the fourth one, COpenCombineHelpers, is considered private. Don't import it in your projects).

OpenCombine itself does not have any dependencies. Not even Foundation or Dispatch. If you want to use OpenCombine with Dispatch (for example for using DispatchQueue as Scheduler for operators like debounce, receive(on:) etc.), you will need to import both OpenCombine and OpenCombineDispatch. The same applies to Foundation: if you want to use, for instance, NotificationCenter or URLSession publishers, you'll need to also import OpenCombineFoundation

Swift Package Manager
Swift Package

To add OpenCombine to your SPM package, add the OpenCombine package to the list of package and target dependencies in your Package.swift file.

dependencies: [
    .package(url: "https://github.com/broadwaylamb/OpenCombine.git", from: "0.8.0")
targets: [
    .target(name: "MyAwesomePackage", dependencies: ["OpenCombine",

OpenCombine can also be added as a SPM dependency directly in your Xcode project (requires Xcode 11 upwards).

To do so, open Xcode, use FileSwift PackagesAdd Package Dependency…, enter the repository URL, choose the latest available version, and activate the checkboxes:

Select the OpenCombine and OpenCombineDispatch targets


To add OpenCombine to a project using CocoaPods, add OpenCombine and OpenCombineDispatch to the list of target dependencies in your Podfile.

pod 'OpenCombine', '~> 0.8'
pod 'OpenCombineDispatch', '~> 0.8'
pod 'OpenCombineFoundation', '~> 0.8'


In order to work on this project you will need Xcode 10.2 and Swift 5.0 or later.

Please refer to the issue #1 for the list of operators that remain unimplemented, as well as the RemainingCombineInterface.swift file. The latter contains the generated interface of Apple's Combine from the latest Xcode 11 version. When the functionality is implemented in OpenCombine, it should be removed from the RemainingCombineInterface.swift file.

You can refer to this gist to observe Apple's Combine API changes between different Xcode (beta) versions, or to this gist to see the relevant contents of the .swiftinterface file for Combine.

You can run compatibility tests against Apple's Combine. In order to do that you will need either macOS 10.14 with iOS 13 simulator installed (since the only way we can get Apple's Combine on macOS 10.14 is using the simulator), or macOS 10.15 (Apple's Combine is bundled with the OS). Execute the following command from the root of the package:

$ make test-compatibility

Or enable the -DOPENCOMBINE_COMPATIBILITY_TEST compiler flag in Xcode's build settings. Note that on iOS only the latter will work.

NOTE: Before starting to work on some feature, please consult the GitHub project to make sure that nobody's already making progress on the same feature! If not, then please create a draft PR to indicate that you're beginning your work.


Some publishers in OpenCombine (like Publishers.MapKeyPath, Publishers.Merge) exist in several different flavors in order to support several arities. For example, there are also Publishers.MapKeyPath2 and Publishers.MapKeyPath3, which are very similar but different enough that Swift's type system can't help us here (because there's no support for variadic generics). Maintaining multiple instances of those generic types is tedious and error-prone (they can get out of sync), so we use the GYB tool for generating those instances from a template.

GYB is a Python script that evaluates Python code written inside a template file, so it's very flexible — templates can be arbitrarily complex. There is a good article about GYB on NSHipster.

GYB is part of the Swift Open Source Project and can be distributed under the same license as Swift itself.

GYB template files have the .gyb extension. Run make gyb to generate Swift code from those templates. The generated files are prefixed with GENERATED- and are checked into source control. Those files should never be edited directly. Instead, the .gyb template should be edited, and after that the files should be regenerated using make gyb.

Debugger Support

The file opencombine_lldb.py defines some lldb type summaries for easier debugging. These type summaries improve the way lldb and Xcode display some OpenCombine values.

To use opencombine_lldb.py, figure out its full path. Let's say the full path is ~/projects/OpenCombine/opencombine_lldb.py. Then the following statement to your ~/.lldbinit file:

command script import ~/projects/OpenCombine/opencombine_lldb.py

Currently, opencombine_lldb.py defines type summaries for these types:

  • Subscribers.Demand
  • That's all for now.


Stars: 1152


Used By

Total: 0


0.8.0 - 2020-01-17 14:16:14

This release is compatible with Xcode 11.3.1.


  • Publishers.ReplaceEmpty (#122, thank you @spadafiva)
  • NotificationCenter.Publisher (#84)
  • URLSession.DataTaskPublisher (#127)
  • Publishers.DropUntilOutput (#136)
  • Publishers.CollectByCount (#137)
  • Publishers.AssertNoFailure (#138)
  • Publishers.Buffer (#143)


  • Fixed integer overflows in DispatchQueue.SchedulerTimeType.Stride (#126, #130)
  • Fixed the 'default will never be executed' warning on non-Darwin platforms (like Linux) (#129)

Known issues

  • The default implementation of the objectWillChange requirement of the ObservableObject protocol is not available in Swift 5.1.

0.7.0 - 2019-12-10 23:47:28

This release is compatible with Xcode 11.2.1.


  • Publishers.Delay (#114)
  • Publishers.ReceiveOn (#115)
  • Publishers.SubscribeOn (#116)
  • Publishers.MeasureInterval (#117)
  • Publishers.Breakpoint (#118)
  • Publishers.HandleEvents (#118)
  • Publishers.Concatenate (#90)

Known issues

  • The default implementation of the objectWillChange requirement of the ObservableObject protocol is not available in Swift 5.1.

0.6.0 - 2019-11-26 16:03:18

This release is compatible with Xcode 11.2.1.

Thread safety

  • Publishers.IgnoreOutput has been audited for thread safety (#88)
  • Publishers.DropWhile and Publishers.TryDropWhile have been audited for thread safety (#87)


  • Publishers.Output (#91)
  • Record (#100)
  • Publishers.RemoveDuplicates, Publishers.TryRemoveDuplicates (#89)
  • Publishers.PrefixWhile, Publishers.TryPrefixWhile (#89)
  • Future (#107, thanks @MaxDesiatov!)


  • The behavior of the Publishers.Encode and Publishers.Decode subscriptions is fixed (#112)
  • The behavior of the Publishers.IgnoreOutput subscription is fixed (#88)
  • The behavior of the Publishers.Print subscription is fixed (#92)
  • The behavior of the Publishers.ReplaceError subscription is fixed (#89)
  • The behavior of the Publishers.Filter and Publishers.TryFilter subscriptions is fixed (#89)
  • The behavior of the Publishers.CompactMap and Publishers.TryCompactMap subscriptions is fixed (#89)
  • The behavior of the Publishers.Multicast subscription is fixed (#110)
  • Publishers.FlatMap is reimplemented from scratch. Its behavior is fixed in many ways, it now fully matches that of Combine (#89)
  • @Published property wrapper is fixed! (#112)
  • The behavior of DispatchQueue.SchedulerTimeType is fixed to match that of the latest SDKs (#96)
  • OpenCombine is now usable on 32 bit platforms. Why? Because we can.

Known issues

  • The default implementation of the objectWillChange requirement of the ObservableObject protocol is not available in Swift 5.1.

0.5.0 - 2019-10-17 11:51:15

This release is compatible with Xcode 11.1.


  • Publishers.MapKeyPath (#71)
  • Publishers.Reduce (#76)
  • Publishers.TryReduce (#76)
  • Publishers.Last (#76)
  • Publishers.LastWhere (#76)
  • Publishers.TryLastWhere (#76)
  • Publishers.AllSatisfy (#76)
  • Publishers.TryAllSatisfy (#76)
  • Publishers.Contains (#76)
  • Publishers.ContainsWhere (#76)
  • Publishers.TryContainsWhere (#76)
  • Publishers.Collect (#76)
  • Publishers.Comparison (#76)
  • Publishers.Drop (#70, thank you @5sw!)
  • Publishers.Scan (#83, thank you @epatey!)
  • Publishers.TryScan (#83, thank you @epatey!)


  • Publishers.Print doesn't print a redundant whitespace anymore.

Known issues

  • @Published property wrapper doesn't work yet

0.4.0 - 2019-10-08 08:34:05

This release is compatible with Xcode 11.1.

Thread safety

  • SubjectSubscriber (which is used when you subscribe a subject to a publisher) has been audited for thread-safety
  • Publishers.Multicast has been audited for thread safety (#63)
  • Publishers.TryMap has been audited for thread safety
  • Just has been audited for thread safety
  • Optional.Publisher has been audited for thread safety
  • Publishers.Sequence has been audited for thread safety
  • Publishers.ReplaceError has been audited for thread safety
  • Subscribers.Assign has been audited for thread safety
  • Subscribers.Sink has been audited for thread safety


  • The semantics of Publishers.Print, Publishers.TryMap have been fixed
  • Fix iterator.next() being called twice in Publishers.Sequence (#62)
  • The default initializer of CombineIdentifier (the one that takes no arguments) is now much faster (#66, #69)
  • When Publishers.Sequence subscription is cancelled while it emits values, the cancellation is respected (#73, thanks @5sw!)


  • DispatchQueueScheduler (#46)
  • Equatable conformances for First, ReplaceError
  • Added eraseToAnyPublisher() method (#59, thanks @evyasafhouzz for reporting!)
  • Publishers.MakeConnectable (#61)
  • Publishers.Autoconnect (#60)
  • Publishers.Share (#60)

Known issues

  • @Published property wrapper doesn't work yet

0.3.0 - 2019-09-13 15:04:41

Among other things this release is compatible with Xcode 11.0 GM seed.


  • Store newly send value in internal variable inside CurrentValueObject (#39, thanks @FranzBusch!)


  • Filter/TryFilter (#22, thanks @spadafiva!)
  • First/FirstWhere/TryFirstWhere (#22, thanks again @spadafiva!)
  • CompactMap/TryCompacrMap (#32)
  • IgnoreOutput (#44, thanks @epatey!)
  • ReplaceError (#50, thanks @vladiulianbogdan!)
  • FlatMap (#45, thanks again @epatey!)

Known issues

  • @Published property wrapper doesn't work yet

0.2.0 - 2019-07-31 20:57:44

Updated for the newest Xcode 11.0 beta 5

0.1.0 - 2019-07-04 15:40:59

The first pre-pre-pre-alpha release is here!

Lots of stuff still unimplemented.

For now we have:

  • Just
  • Publishers.Decode
  • Publishers.DropWhile
  • Publishers.Empty
  • Publishers.Encode
  • Publishers.Fail
  • Publishers.Map
  • Publishers.Multicast
  • Publishers.Once
  • Publishers.Optional
  • Publishers.Print
  • Publishers.Sequence
  • Subscribers.Assign
  • Subscribers.Completion
  • Subscribers.Demand
  • Subscribers.Sink
  • AnyCancellable
  • AnyPublisher
  • AnySubject
  • AnySubscriber
  • Cancellable
  • CombineIdentifier
  • ConnectablePublisher
  • CurrentValueSubject
  • CustomCombineIdentifierConvertible
  • ImmediateScheduler
  • PassthroughSubject
  • Publisher
  • Result
  • Scheduler
  • Subject
  • Subscriber
  • Subscription