tcldr
Entwine
Swift

Testing tools and utilities for Apple's Combine framework.

Last updated Jun 17, 2026
447
Stars
26
Forks
3
Issues
0
Stars/day
Attention Score
38
Language breakdown
Swift 99.5%
Awk 0.4%
Makefile 0.0%
โ–ธ Files click to expand
README

Entwine

CI @tcldr1

Accessories for Apple's Combine Framework.


About

Entwine consists of three libraries (over two repositories) to be used in conjuction with Apple's Combine framework: The package currently includes a ReplaySubject, a withLatest(from:) operator and a Publishers.Factory for rapidly defining publishers inline from any source.

View the README for the Entwine Utilities Library

  • The EntwineTest library_ consists of tools for verifying expected behavior of Combine sequences. It houses
a TestScheduler that uses virtual time, a TestablePublisher that schedules a user-defined sequence of elements in absolute or relative time, and a TestableSubscriber that record a time-stamped list of events that can be compared against expected behavior.

View the README for the EntwineTest Library

making RxSwift and Combine work together seamlessly.

View the README for the EntwineRx Library

Note: EntwineRx is maintained as a separate Swift package to minimize the SPM dependency graph.


Quick start guide

Create Combine publishers from any source

Use the Publishers.Factory publisher from the
Entwine_ package to effortlessly create a publisher that meets Combine's backpressure requirements from any source. Find out more about the Entwine Utilities_ library.

Inline publisher creation for PhotoKit authorization status:

import Entwine

let photoKitAuthorizationStatus = Publishers.Factory<PHAuthorizationStatus, Never> { dispatcher in let status = PHPhotoLibrary.authorizationStatus() dispatcher.forward(status) switch status { case .notDetermined: PHPhotoLibrary.requestAuthorization { newStatus in dispatcher.forward(newStatus) dispatcher.forward(completion: .finished) } default: dispatcher.forward(completion: .finished) } return AnyCancellable {} }

Unit test Combine publisher sequences

Use the TestScheduler, TestablePublisher and TestableSubscriber to simulate Combine sequences and test against expected output. Find out more about the EntwineTest_ library

Testing Combine's map(:) operator:_

import XCTest
import EntwineTest
    
func testMap() {
    
    let testScheduler = TestScheduler(initialClock: 0)
    
    // creates a publisher that will schedule it's elements relatively, at the point of subscription
    let testablePublisher: TestablePublisher<String, Never> = testScheduler.createRelativeTestablePublisher([
        (100, .input("a")),
        (200, .input("b")),
        (300, .input("c")),
    ])
    
    let subjectUnderTest = testablePublisher.map { $0.uppercased() }
    
    // schedules a subscription at 200, to be cancelled at 900
    let results = testScheduler.start { subjectUnderTest }
    
    XCTAssertEqual(results.recordedOutput, [
        (200, .subscription),           // subscribed at 200
        (300, .input("A")),             // received uppercased input @ 100 + subscription time
        (400, .input("B")),             // received uppercased input @ 200 + subscription time
        (500, .input("C")),             // received uppercased input @ 300 + subscription time
    ])
}

Bridge your RxSwift view models to Combine and use with SwiftUI

First, make sure you add the EntwineRx Swift Package_ (located in an external repo) as a dependency to your project.

Example coming soon


Requirements

Entwine sits on top of Apple's Combine framework and therefore requires Xcode 11 and is has minimum deployment targets of macOS 10.15, iOS 13, tvOS 13 or watchOS 6.

Installation

Entwine is delivered via a Swift Package and can be installed either as a dependency to another Swift Package by adding it to the dependencies section of a Package.swift file or to an Xcode 11 project by via the File -> Swift Packages -> Add package dependency... menu in Xcode 11.

Documentation

Documentation for each package is available at:

Copyright and license

This project is released under the MIT license


ยฉ 2026 GitRepoTrend ยท tcldr/Entwine ยท Updated daily from GitHub