Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
icanzilb committed Aug 15, 2019
1 parent 3286445 commit 6dc9a09
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added Assets/combine-printout.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions Package.swift
@@ -0,0 +1,23 @@
// swift-tools-version:5.1

import PackageDescription

let package = Package(
name: "CombinePrintout",
platforms: [
.iOS(.v13),
],
products: [
.library(
name: "CombinePrintout",
targets: ["CombinePrintout"]),
],
targets: [
.target(
name: "CombinePrintout",
dependencies: []),
.testTarget(
name: "CombinePrintoutTests",
dependencies: ["CombinePrintout"]),
]
)
62 changes: 61 additions & 1 deletion README.md
@@ -1,2 +1,62 @@
# CombinePrintout
A Combine micro debugging package

A Combine micro debugging framework. It helps you log subscription events to the console so you can track their life cycle.

## Usage

#### A debugging print sink

The built-in `print()` operator is useful but you still need to add a subscriber to your subscription. `printSink()` is a subscriber that you can use to debug a subscription without the need to add a separate subscriber like so:

```swift
Just(["One", "Two"])
.printSink()
```

`printSink()` will subscribe the publisher and log all events like so:

```none
Sink: output(["One", "Two"])
Sink: finished
```

#### A debugging print cancellable

If you're building more complex memory management logic or not sure when are your cancellables released you can use `printCancellable()` to log a given `Cancellable`'s life cycle like so:

```swift
Just(["One", "Two"])
.assign(to: \.model, on: self)
.printCancellable()
.store(in: &subscriptions)
```

`printCancellable()` wraps the `AnyCancellable` returned from `assign(to:on:)` and logs all the received events:

```none
Cancellable: init
...
(self.subscriptions is released from memory)
...
Cancellable: cancel
Cancellable: deinit
```

## Installation

### Swift Package Manager

Add the following dependency to your **Package.swift** file:

```swift
.package(url: "https://github.com/combineopensource/CombinePrintout, from: "0.2")
```
## License
CombineOpenSource is available under the MIT license. See the LICENSE file for more info.
## Credit
Copyright (c) 2019 Combine Open Source
Created by: Marin Todorov
40 changes: 40 additions & 0 deletions Sources/CombinePrintout/CombinePrintout.swift
@@ -0,0 +1,40 @@
import Combine

class PrintCancellable: Cancellable {
let wrapped: AnyCancellable
let id: String

init(_ wrapped: AnyCancellable, id: String? = nil) {
self.wrapped = wrapped
self.id = id ?? ""
Swift.print("Cancellable: init \(self.id)")
}

func cancel() {
wrapped.cancel()
Swift.print("Cancellable: cancel \(id)")
}

deinit {
Swift.print("Cancellable: deinit \(id)")
}
}

extension Cancellable {

/// A debugging `Cancellable` wrapper that prints out `Cancellable` life cycle events.
/// - Parameter id: An optional identifier to print along the output.
public func printCancellable(id: String? = nil) -> AnyCancellable {
return AnyCancellable(PrintCancellable(AnyCancellable(self), id: id))
}
}

extension Publisher {

/// A debugging sink that prints all received events.
/// - Parameter id: An optional identifier to print along the output.
public func printSink(id: String = "") -> AnyCancellable {
return sink(receiveCompletion: { Swift.print("Sink: \($0) \(id)") },
receiveValue: { Swift.print("Sink: output(\($0)) \(id)") })
}
}
15 changes: 15 additions & 0 deletions Tests/CombinePrintoutTests/CombinePrintoutTests.swift
@@ -0,0 +1,15 @@
import XCTest
@testable import CombinePrintout

final class CombinePrintoutTests: XCTestCase {
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(CombinePrintout().text, "Hello, World!")
}

static var allTests = [
("testExample", testExample),
]
}
9 changes: 9 additions & 0 deletions Tests/CombinePrintoutTests/XCTestManifests.swift
@@ -0,0 +1,9 @@
import XCTest

#if !canImport(ObjectiveC)
public func allTests() -> [XCTestCaseEntry] {
return [
testCase(CombinePrintoutTests.allTests),
]
}
#endif
7 changes: 7 additions & 0 deletions Tests/LinuxMain.swift
@@ -0,0 +1,7 @@
import XCTest

import CombinePrintoutTests

var tests = [XCTestCaseEntry]()
tests += CombinePrintoutTests.allTests()
XCTMain(tests)

0 comments on commit 6dc9a09

Please sign in to comment.