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

Overview

OpenCombine

OpenCombine 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 WebAssembly.

Installation

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.

If you develop code for multiple platforms, you may find it more convenient to import the OpenCombineShim module instead. It conditionally re-exports Combine on Apple platforms (if available), and all OpenCombine modules on other platforms. You can import OpenCombineShim only when using SwiftPM. It is not currently available for CocoaPods.

Swift Package Manager
Swift Package

To add OpenCombine to your SwiftPM package, add the OpenCombine package to the list of package and target dependencies in your Package.swift file. OpenCombineDispatch and OpenCombineFoundation products are currently not supported on WebAssembly. If your project targets WebAssembly exclusively, you should omit them from the list of your dependencies. If it targets multiple platforms including WebAssembly, depend on them only on non-WebAssembly platforms with conditional target dependencies.

dependencies: [
    .package(url: "https://github.com/OpenCombine/OpenCombine.git", from: "0.12.0")
],
targets: [
    .target(
        name: "MyAwesomePackage",
        dependencies: [
            "OpenCombine",
            .product(name: "OpenCombineFoundation", package: "OpenCombine"),
            .product(name: "OpenCombineDispatch", package: "OpenCombine")
        ]
    ),
]
Xcode

OpenCombine can also be added as a SwiftPM 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

CocoaPods

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

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

Contributing

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 repo to observe Apple's Combine API and documentation changes between different Xcode (beta) versions.

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.

Releasing a new version

  1. Create a new branch from master and call it release/<major>.<minor>.<patch>.

  2. Replace the usages of the old version in README.md with the new version (make sure to check the Swift Package Manager and CocoaPods sections).

  3. Bump the version in OpenCombine.podspec, OpenCombineDispatch.podspec and OpenCombineFoundation.podspec. In the latter two you will also need to set the spec.dependency "OpenCombine" property to the previous version. Why? Because otherwise the pod lib lint command that we run on our regular CI will fail when validating the OpenCombineDispatch and OpenCombineFoundation podspecs, since the dependencies are not yet in the trunk. If we set the dependencies to the previous version (which is already in the trunk), everything will be fine. This is purely to make the CI work. The clients will not experience any issues, since the version is specified as >=.

  4. Create a pull request to master for the release branch and make sure the CI passes.

  5. Merge the pull request.

  6. In the GitHub web interface on the releases page, click the Draft a new release button.

  7. The Tag version and Release title fields should be filled with the version number.

  8. The description of the release should be consistent with the previous releases. It is a good practice to divide the description into several sections: additions, bugfixes, known issues etc. Also, be sure to mention the nicknames of the contributors of the new release.

  9. Publish the release.

  10. Switch to the master branch and pull the changes.

  11. Push the release to CocoaPods trunk. For that, execute the following commands:

    pod trunk push OpenCombine.podspec --verbose --allow-warnings
    pod trunk push OpenCombineDispatch.podspec --verbose --allow-warnings
    pod trunk push OpenCombineFoundation.podspec --verbose --allow-warnings
    

    Note that you need to be one of the owners of the pod for that.

GYB

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.
Comments
  • Add support for SwiftWasm with CI and tests

    Add support for SwiftWasm with CI and tests

    WebAssembly support for atomics and multi-threading isn't fully standardized yet, and it not supported in SwiftWasm at the moment. Because of this Dispatch is unavailable, and all Combine-related Foundation stuff is unavailable too. Tests related to this are disabled. Locking functions are replaced with no-op shims.

    enhancement 
    opened by MaxDesiatov 20
  • URLSession.dataTaskPublisher for OpenCombine?

    URLSession.dataTaskPublisher for OpenCombine?

    Hi there

    So I am on the home stretch, but I have a few issues. Firstly: I am getting

    error: value of type 'URLSession' has no member 'dataTaskPublisher'
                self.urlSession.dataTaskPublisher(for: request)
    

    Is there an OpenCombine equivalent to use dataTaskPublisher?

    Secondly, I am also getting:

    error: value of type 'Any' has no member 'tryMap'
                    .tryMap { (data, response) -> Data in
    

    Is this also functional in OpenCombine?

    Thanks once again 🙏🏻

    missing functionality 
    opened by doronkatz 19
  • FlatMap

    FlatMap

    I'm taking a stab at FlatMap. In support of operators that need serialization of sending values from multiple upstream/child subscriptions, I've implemented a simple/fast SerializedWorkQueue that adheres to the Combine threading rules and avoids unnecessary context switches.

    Remaining work:

    • [x] Clean up and ensure all completion/failures paths are correct.
      • [x] Clean up and complete with .failed if either upstream or any children fail.
      • [x] Complete with .finished only after upstream and all children have completed (i.e. add refcounting of active subscriptions) AND all buffer values have been sent.
    • [x] Figure out and add support for maxPublishers
    • [x] Figure out non-trivial handling of demand for child subscriptions and implement it.
      • [x] Basic child demand scenarios work
      • [x] Add support for downstream demand going from .unlimited to .max(x)
      • [x] Add support for downstream demand going from .max(x) to .unlimited
    • [x] Add unit tests
    • [x] Factor out common base class from Inner class to be shared with all merge like operators.
    missing functionality 
    opened by epatey 14
  • OpenCombine organization?

    OpenCombine organization?

    I'm currently maintaining a few forks of open-source libraries that make those compatible with OpenCombine: GRDBOpenCombine and its dependency OpenCombineExpectations. I'd appreciate any input and contributions to these forks, and maybe some coordinated effort to push a more sane support for "polyfill" libraries in future versions of Swift. If the latter happens, we probably even could upstream changes from these forks to their origin repositories.

    Either way, it would make sense to maintain these forks, proposals, and related helper projects under one umbrella OpenCombine organization with an open list of maintainers. This would make the project more visible and I hope attract more attention and contributors. I'm not sure if existing OpenCombine organization is the one previously created for this purpose, if not maybe something like OpenCombineHQ could work as a name just as well.

    help wanted gardening 
    opened by MaxDesiatov 12
  • CocoaPods support

    CocoaPods support

    Adding support for CocoaPods. This required to add three separate podspecs, one for the C++ helpers, one for OpenCombine and one for OpenCombineDispatch. Created a local example project and tested that it build with both dynamic frameworks and static libraries. ✅

    As os_unfair_lock is only available on versions above the minimum deployment target, warnings are produced. There is a check in place that they're actually not used when they're not available. Therefore passing --allow-warnings to pod lib lint should be fine.

    This PR does not expose the tests via a test_spec as this would've required adding a podspec to GottaGoFast. As this dependency was recently dropped, let's tackle this in a future PR.

    Fixes #48

    opened by ohitsdaniel 10
  • @propertyWrapper Published

    @propertyWrapper Published

    Hello! I've implemented this interface. That allows use construction like this: @Published var value: String? And bind and subscribe: $value.assign(to: \.text, on: textLabel) I hope that will be helpful.

    missing functionality 
    opened by beastgrim 10
  • Update for Xcode 13

    Update for Xcode 13

    • [x] Update tests to pass in Combine compatibility mode
    • [x] Fix OpenCombine so all tests pass
    • [x] Implement the new APIs
    • [x] Write tests for the new APIs
    • [x] Enable testing with Swift 5.5 on Ubuntu (when Swift 5.5 docker image is released)
    opened by broadwaylamb 9
  • Implementation for ObservableObject

    Implementation for ObservableObject

    (picking up #93)

    • [x] Make it work with generic classes.
    • [x] Add tests for NSObject subclasses.
    • [x] Add tests where a class contains a field of resilient struct type
    • [x] Add CI jobs for Apple platforms without Swift runtime (before iOS 12.2/macOS 10.14.4).
    • [x] Add CI jobs for Apple platforms that support Swift 5.1.
    • [x] Ideally, test on a 32 bit Apple platform.
    • [ ] Remove unneeded C++ code.
    • [ ] Resolve FIXMEs
    missing functionality 
    opened by broadwaylamb 8
  • Delay

    Delay

    Hello! I've done some work for "Delay" feature. It's not complete yet because I need advice for some troubles. First: It can't be completed until "FlatMap" is done. Second: I can't finish tests for "Delay" because we don't have RunLoop in OpenCombine. But I've tested all functionality on iOS and all works as expected with this implementation (all existed tests pass).

    Best regards!

    missing functionality 
    opened by beastgrim 8
  • Store newly send value in internal variable inside CurrentValueObject

    Store newly send value in internal variable inside CurrentValueObject

    This should fix #38 but I think it breaks the synchronisation test. I tried fixing it and from what I can see everything is locked properly but apparently I am missing something since that test is flaky for me locally. Would be great if you can have a look and tell me what you think about this implementation.

    opened by FranzBusch 8
  • Implemented comparison operators (min and max)

    Implemented comparison operators (min and max)

    I implemented most of this a few days back, mostly reusing what's currently in the repo.

    There is a bug with max operator with custom comparison closure, hence the test fail, but I thought I'd open up a PR and see if you guys have any ideas

    The bug itself is probably pretty straight-forward to fix, I'm just having a hard time reasoning what min and max operators with custom comparison closures are supposed to do in the first place. I assume it's just a matter of somehow "inverting" the logic for min and max operators, after the custom closure is executed. The test that's failing is called testCustomMaxSendsCorrectValue.

    Let me know how all of this looks, and I can address any feedback asap.

    On a side note -- one thing that slowed me down quite a bit was trying to squeeze in some of the code with lengthy generic names into single lines. Is there a reason with went for 90 char/line limit? It seems pretty strict, leaving basically half of my laptop screen empty. On projects I previously worked on, the number was usually in 130-150 range. Just curious if it's open for debate or not :)

    missing functionality 
    opened by ilijapuaca 8
  • Unable to build on Ubuntu 22.04.1

    Unable to build on Ubuntu 22.04.1

    Building for debugging... */OpenCombine/Sources/COpenCombineHelpers/COpenCombineHelpers.cpp:10:10: fatal error: 'atomic' file not found #include ^~~~~~~~ 1 error generated. [1/10] Compiling COpenCombineHelpers COpenCombineHelpers.cpp

    opened by GothStar 0
  • Add primary associated type support

    Add primary associated type support

    When Swift released 5.7 in Xcode 14.0, Combine framework has updated its protocol interface to support primary associated type support.

    eg.

    // Latest Combine
    public protocol Publisher<Output, Failure>
    
    // Current OpenCombine and old Combine(iOS 15-)
    public protocol Publisher
    

    Adding such feature support enable us to use some Publisher<Int, Error> without needing to convert it to AnyPublisher.

    func loadUser(
        withID id: User.ID
    ) -> some Publisher<User, Error> {
        urlSession
            .dataTaskPublisher(for: urlForLoadingUser(withID: id))
            .map(\.data)
            .decode(type: User.self, decoder: decoder)
    }
    

    See more info at Combining opaque return types with primary associated types

    opened by Kyle-Ye 1
  • Add primary associated types

    Add primary associated types

    Apple's official Combine framework also implemented primary associated types feature introduced in swift 5.7.

    https://developer.apple.com/documentation/combine/connectablepublisher https://developer.apple.com/documentation/combine/publisher https://developer.apple.com/documentation/combine/subscriber https://developer.apple.com/documentation/combine/subject https://developer.apple.com/documentation/combine/scheduler

    so I changed ConnectablePublisher, Publisher, Subscriber, Subject, Scheduler to support primary associated types as well.

    opened by danny1113 3
  • would be nice to be able to use

    would be nice to be able to use "@Published" directive in earlier Swift versions that do not know it

    while trying to implement OpenCombine to mimic missing Combine Framework in example in Xcode 11.3.1 projects where Swift does also not support @Published directive (nor @Bind , @StateObject or @ObservedObject) one could do something like..

    @propertyWrapper
    struct Published<T> {
        var wrappedValue: T {
            willSet { /*...*/ }
            didSet { /*...*/ }
        }
        init(wrappedValue: T) {
            
            // * -- maybe magic here! -- */
            
            /* or do more specific stuff.. ^^
            switch (wrappedValue) {
            //case is Optional<Any>.Type :
                //break
            case is Bool :
                break
            case is Error :
                break
            case is Optional<Error>.Type :
                break
            default: break
            }
            */
            self.wrappedValue = wrappedValue
        }
    }
    

    to implement such feature in Swift version prior .. where @propertyWrapper directive is available. So the question is what should such wrapper look like in its inner logic?

    opened a question in StackOverflow

    it could be wrapped also in preprocessor directives like #if !canImport(Combine) or similar to limit where it would be applied in projects

    also see: swiftbysundell.com/accessing-a-swift-property-wrappers

    opened by designerfuzzi 2
  • [Bug]The Publishers.ReceiveOn may lead to subscriber never receive the published signal when scheduler is concurrent queue.

    [Bug]The Publishers.ReceiveOn may lead to subscriber never receive the published signal when scheduler is concurrent queue.

    For Future type publisher, it send signal then send completion to the Publishers.ReceiveOn.

    In Publishers.ReceiveOn:

    for signal:

    scheduler.schedule(options: options) {
       self.scheduledReceive(input)
    }
    

    for completion:

    scheduler.schedule(options: options) {
       self.scheduledReceive(completion: completion)
    }
    

    but the scheduler may execute the completion command before signal, in this case, the state.subscription is nil then returned.

    private func scheduledReceive(_ input: Input) {
      lock.lock()
      guard state.subscription != nil else {
        lock.unlock()
        return
      }
       
       // ...
    }
    

    This result is not match expectations.

    And the Apple's Combine has the same bug yet 😂.

    We should promise the subscriber will always receive the signal?

    Some solution code:

    // for signal.
    lockedActions.write().safeRun({
        $0.pointee.insert({ [weak self] in self?.scheduledReceive(input) }, at: 0)
    })
    scheduler.schedule(options: options) {
        self.lockedActions.write().safeRun({ $0.pointee.popLast()?() })
    }
    
    // for complection.
    lockedActions.write().safeRun({
        $0.pointee.insert({ [weak self] in self?.scheduledReceive(completion: completion) }, at: 0)
    })
    scheduler.schedule(options: options) {
        self.lockedActions.write().safeRun({ $0.pointee.popLast()?() })
    }
    
    opened by dito010 0
Releases(0.13.0)
  • 0.13.0(Feb 1, 2022)

    This release is compatible with Xcode 13.2.

    Additions

    • Windows support (thank you @MaxDesiatov!)
    • Publishers.Throttle (#195, thank you @stuaustin)
    • Publishers.PrefixUntilOutput (#206)
    • Publishers.Zip (#222, thank you @MaxDesiatov and @ArthurChi)
    • async/await extensions: Future.value and Publisher.values (#219)

    Bugfixes

    • Fixed reentrancy bugs in Subscribers.Sink and Subscribers.Assign (#210)
    • Fixed lifecycle bugs in Publishers.Concatenate (#210)
    Source code(tar.gz)
    Source code(zip)
  • 0.12.0(Jan 29, 2021)

    This release adds a new OpenCombineShim product that will conditionally re-export either Combine on Apple platforms, or OpenCombine on other platforms. Additionally, ObservableObject protocol is now available and working on all platforms.

    A bug with Timer(timeInterval:repeats:block:) firing immediately not accounting for the passed timeInterval is fixed.

    Merged pull requests:

    Source code(tar.gz)
    Source code(zip)
  • 0.11.0(Oct 29, 2020)

    This release is compatible with Xcode 12.1.

    Additions

    • Publisher.assigned(to:) method that accepts a Published.Publisher.
    • New Publisher.switchToLatest() overloads.
    • New Publisher.flatMap(maxPublishers:_:) overloads.
    • Optional.publisher property.
    • New _Introspection protocol that allows to track and explore the subscription graph and data flow.

    Bugfixes

    • The project should now compile without warnings.
    • The following entities have been updated to match the behavior of the newest Combine version:
      • Subscribers.Assign
      • Publishers.Breakpoint
      • Publishers.Buffer
      • CombineIdentifier
      • Publishers.CompactMap
      • Publishers.Concatenate
      • Publishers.Debounce
      • Publishers.Delay
      • DispatchQueue.SchedulerTimeType.Stride
      • Publishers.Drop
      • Publishers.Encode
      • Publishers.Decode
      • Publishers.Filter
      • Publishers.HandleEvents
      • Publishers.IgnoreOutput
      • Publishers.MeasureInterval
      • OperationQueue scheduler
      • Published
      • Publishers.ReceiveOn
      • Publishers.ReplaceError
      • RunLoop scheduler
      • Publishers.Sequence
      • Subscribers.Sink
      • Publishers.SubscribeOn
      • Publishers.Timeout
      • Timer publisher

    Known issues

    • The default implementation of the objectWillChange requirement of the ObservableObject protocol is not available in Swift 5.1 and later.
    Source code(tar.gz)
    Source code(zip)
  • 0.10.2(Oct 23, 2020)

    Bugfixes

    • Fixed a crash caused by recursive acquisition of a non-recursive lock in SubbjectSubscriber (#186, thanks @stuaustin for the bug report)

    Known issues

    • The default implementation of the objectWillChange requirement of the ObservableObject protocol is not available in Swift 5.1 and later.
    Source code(tar.gz)
    Source code(zip)
  • 0.10.1(Oct 4, 2020)

    Bugfixes

    • Fixed build errors on Linux with Swift 5.0 and Swift 5.3 toolchains (thanks, @adamleonard and @devmaximilian)

    Known issues

    • The default implementation of the objectWillChange requirement of the ObservableObject protocol is not available in Swift 5.1 and later.
    Source code(tar.gz)
    Source code(zip)
  • 0.10.0(Jun 28, 2020)

    This release is compatible with Xcode 11.5.

    Additions

    • Timer.publish(every:tolerance:on:in:options:) (#156, thank you @MaxDesiatov)
    • OperationQueue scheduler (#165)
    • Publishers.Timeout (#164)
    • Publishers.Debounce (#133)

    Bugfixes

    • PassthroughSubject, CurrentValueSubject and Future have been rewritten from scratch. They are now faster, more correct and no longer leak subscriptions (#170).

    Known issues

    • The default implementation of the objectWillChange requirement of the ObservableObject protocol is not available in Swift 5.1 and later.
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Jun 12, 2020)

    This release is compatible with Xcode 11.5.

    Additions

    • The Subscribers.Demand struct can be nicely formatted in LLDB (#146, thank you @mayoff).
    • Publishers.SwitchToLatest (#142).
    • The RunLoop scheduler in OpenCombineFoundation (#131).
    • Publishers.Catch and Publishers.TryCatch (#140).

    Bugfixes

    • Worked around a bug in the Swift compiler when building the COpenCombineHelpers target (#145, thank you @mayoff).
    • Improved documentation.

    Known issues

    • The default implementation of the objectWillChange requirement of the ObservableObject protocol is not available in Swift 5.1 and later.
    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Jan 17, 2020)

    This release is compatible with Xcode 11.3.1.

    Additions

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

    Bugfixes

    • 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.
    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Dec 10, 2019)

    This release is compatible with Xcode 11.2.1.

    Additions

    • 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.
    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Nov 26, 2019)

    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)

    Additions

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

    Bugfixes

    • 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.
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Oct 17, 2019)

    This release is compatible with Xcode 11.1.

    Additions

    • 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!)

    Bugfixes

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

    Known issues

    • @Published property wrapper doesn't work yet
    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Oct 8, 2019)

    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

    Bugfixes

    • 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!)

    Additions

    • 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
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Sep 13, 2019)

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

    Bugfixes

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

    Additions

    • 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
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Jul 31, 2019)

  • 0.1.0(Jul 4, 2019)

    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
    Source code(tar.gz)
    Source code(zip)
Owner
OpenCombine
OpenCombine
Interactive notification pop-over (aka "Toast) modeled after the iOS AirPods and Apple Pencil indicator.

Interactive notification pop-over (aka "Toast) modeled after the iOS AirPods and Apple Pencil indicator. Installation The recommended way is to use Co

Philip Kluz 108 Nov 11, 2022
UI event handling using Apple's combine framework.

Description Combinative is a library for UI event handling using Apple's combine framework. It doesn't need many dependencies because it is written ma

noppefoxwolf 106 Jan 29, 2022
RxReduce is a lightweight framework that ease the implementation of a state container pattern in a Reactive Programming compliant way.

About Architecture concerns RxReduce Installation The key principles How to use RxReduce Tools and dependencies Travis CI Frameworks Platform Licence

RxSwift Community 125 Jan 29, 2022
📬 A lightweight implementation of an observable sequence that you can subscribe to.

Features Lightweight Observable is a simple implementation of an observable sequence that you can subscribe to. The framework is designed to be minima

Felix M. 133 Aug 17, 2022
ReSwift is a Redux-like implementation of the unidirectional data flow architecture in Swift.

ReSwift is a Redux-like implementation of the unidirectional data flow architecture in Swift. ReSwift helps you to separate three important concerns of your app's components.

null 7.3k Jan 9, 2023
When is a lightweight implementation of Promises in Swift

Description When is a lightweight implementation of Promises in Swift. It doesn't include any helper functions for iOS and OSX and it's intentional, t

Vadym Markov 259 Dec 29, 2022
Very simple Observable and Publisher implementation for iOS apps.

Very simple Observable and Publisher implementation for iOS apps.

Igor Kulman 7 Jun 11, 2022
A New, Modern Reactive State Management Library for Swift and SwiftUI (The iOS implementation of Recoil)

RecoilSwift RecoilSwift is a lightweight & reactive swift state management library. RecoilSwift is a SwiftUI implementation of recoil.js which powered

Holly Li 160 Dec 25, 2022
Bond is a Swift binding framework that takes binding concepts to a whole new level.

Bond, Swift Bond Update: Bond 7 has been released! Check out the migration guide to learn more about the update. Bond is a Swift binding framework tha

Declarative Hub 4.2k Jan 5, 2023
Swift Apps in a Swoosh! A modern framework for creating iOS apps, inspired by Redux.

Katana is a modern Swift framework for writing iOS applications' business logic that are testable and easy to reason about. Katana is strongly inspire

Bending Spoons 2.2k Jan 1, 2023
🐌 snail - An observables framework for Swift

?? snail A lightweight observables framework, also available in Kotlin Installation Carthage You can install Carthage with Homebrew using the followin

Compass 179 Nov 21, 2022
SwiftUI-compatible framework for building browser apps with WebAssembly and native apps for other platforms

SwiftUI-compatible framework for building browser apps with WebAssembly At the moment Tokamak implements a very basic subset of SwiftUI. Its DOM rende

TokamakUI 2k Dec 30, 2022
SwiftUI-compatible framework for building browser apps with WebAssembly and native apps for other platforms

SwiftUI-compatible framework for building browser apps with WebAssembly At the moment Tokamak implements a very basic subset of SwiftUI. Its DOM rende

TokamakUI 2k Dec 29, 2022
EventBroadcaster is a lightweight event handler framework, written in swift for iOS, macOS, tvOS & watchOS applications.

EventBroadcaster is a lightweight event handler framework, written in swift for iOS, macOS, tvOS & watchOS applications.

Ali Samaiee 4 Oct 5, 2022
Open source implementation of Apple's Combine framework for processing values over time.

OpenCombine Open-source implementation of Apple's Combine framework for processing values over time. The main goal of this project is to provide a com

OpenCombine 2.4k Jan 2, 2023
Open-source implementation of Apple's Combine for processing values over time

CombineX 简体中文 Open-source implementation of Apple's Combine for processing values over time. Though CombineX have implemented all the Combine interfac

Luo Xiu 1 Dec 30, 2021
PublisherKit - An open source implementation of Apple's Combine framework for processing asynchronous events over time

Publisher Kit Overview PublisherKit provides a declarative Swift API for processing asynchronous events over time. It is an open source version of App

null 5 Feb 22, 2022
🐵Fooling around with Apples private framework AvatarKit

Fooling around with Apples private framework AvatarKit, the framework used in Messages.app for recording Animoji videos. If you are looking to create your own Animoji, take a look at SBSCustomAnimoji.

Simon Støvring 968 Dec 25, 2022
Streams of values over time

Streams of values over time. Tailored for Swift. ?? Release Roadmap Getting Started Learn about the Core Reactive Primitives in ReactiveSwift, and Bas

null 2.9k Jan 3, 2023
An open source iOS framework for GPU-based image and video processing

GPUImage Brad Larson http://www.sunsetlakesoftware.com @bradlarson [email protected] Overview The GPUImage framework is a BSD-licensed iO

Brad Larson 20k Jan 1, 2023