• This repository has been archived on 29/Nov/2023
  • Stars
    star
    255
  • Rank 155,095 (Top 4 %)
  • Language
    Swift
  • License
    BSD 3-Clause "New...
  • Created almost 2 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Utilities for working with Swift Concurrency

Build Status License Platforms Documentation

ConcurrencyPlus

Utilities for working with Swift Concurrency

⚠️ Better, more-focused libraries have since been extracted from this one. ⚠️

This is a really small library with some types and extensions that may be useful when working with Swift's concurrency system.

  • A TaskQueue for queuing tasks in FIFO ordering
  • CheckedContinuation extensions for improved ergonomics
  • Task extensions for improved ergonomics when used to bridge to non-async code
  • NSXPCConnection extensions for safe async integration
  • MainActor.runUnsafely to help work around incorrectly- or insufficiently-annotated code not under your control
  • OwnershipTransferring to move a non-Sendable value across actor boundaries
  • SendableBox to lie to the compiler about Sendable conformance
  • RelaxedDispatchQueue a very thin DispatchQueue wrapper with relaxed argument sendability constraints

TaskQueue

let queue = TaskQueue()

queue.addOperation {
    await asyncFunction()
    await anotherAsyncFunction()
}

// This can can also return the underlying Task, so you can cancel, or await a value
let task = await queue.addOperation {
    return await makeValue()
}

let value = try await task.value
// Without .ordered, the execution order of these tasks is not well-defined.
Task.ordered {
    event1()
}

Task.ordered(priority: .background) {
    event2()
}

Task.ordered {
    event3()
}

Task Ergonomics

Some handy functions that ease integration with existing callbacks.

func callbackOptionalPair(_ block: @escaping (Int?, Error?) -> Void) {
    Task.relayResult(to: block) {
        // ... return async value or throw...
    }
}

func callbackResult(_ block: @escaping (Result<Int, Error>) -> Void) {
    Task.relayResult(to: block) {
        // ... return async value or throw...
    }
}

func callbackOptionalError(_ block: @escaping (Error?) -> Void) {
    Task.relayResult(to: block) {
        // ... possibly throw...
    }
}

OwnershipTransferring

This is a tool for moving a value across actor boundaries in a way that will keep the compiler happy. It is reasonably unsafe. You have to be very careful about how the moved value is accessed.

actor MyActor {
    let nonSendable: UnsendableType

    init(_ transfer: OwnershipTransferring<UnsendableType>) {
        self.nonSendable = transfer.takeOwnership()
    }
}

let nonSendable = UnsendableType()
let transfer = OwnershipTransferring(nonSendable)

let myActor = MyActor(transfer) // no warnings!

transfer.hasOwnershipBeenTransferred() // true
transfer.takeOwnership() // this will crash

RelaxedDispatchQueue

DispatchQueue now has implicit @Sendable closure arguments. This is a highly-disruptive change, as it makes queues no longer feasible as a means of non-Sendable state protection. Wrap up that that queue and carry on.

let nonSendable = UnsendableType()
let queue = RelaxedDisptachQueue(label: "myqueue")

queue.async {
    nonSendable.doThing() // no warnings
}

Working with XPC

You might be tempted to make your XPC interface functions async. This approach does not handle connection failures and will violate the Structured Concurrency contract, resulting in hangs. See the post "ExtensionKit and XPC" for context.

This little NSXPCConnection extension provides a safe way to get into the async world.

func withContinuation<Service, T>(
    function: String = #function, 
    _ body: (Service, CheckedContinuation<T, Error>) -> Void
) async throws -> T

There are also some extensions on CheckedContinuation to make it easier to use in the context of XPC. These are really handy for resuming from common reply patterns.

Given an XPC service like this in your code:

protocol XPCService {
    func errorMethod(reply: (Error?) -> Void)
    func valueAndErrorMethod(reply: (String?, Error?) -> Void)
    func dataAndErrorMethod(reply: (Data?, Error?) -> Void)
}

The continuation helpers allow bridging like:

try await withContinuation { service, continuation in
    service.errorMethod(reply: continuation.resumingHandler)
}

try await withContinuation { service, continuation in
    service.valueAndErrorMethod(reply: continuation.resumingHandler)
}

// this one will try to use JSONDecoder on the resulting data
try await withContinuation { service, continuation in
    service.dataAndErrorMethod(reply: continuation.resumingHandler)
}

Other Useful Projects

These libraries might be useful and are definitely worth checking out as well.

  • AnyAsyncSequence: super-focused on addressing the lack of type-erased sequences
  • AsyncAlgorithms: Apple-owned reactive extensions to AsyncSequence
  • AsyncExtensions: Companion to AsyncAlgorithms to add additional reactive features
  • Asynchrone: Extensions to bring reactive features to AsyncSequence

Suggestions or Feedback

We'd love to hear from you! Please open up an issue or pull request.

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

More Repositories

1

Impact

Crash capturing library for Apple platforms
C
431
star
2

Neon

A Swift library for efficient, flexible content-based text styling
Swift
297
star
3

Chime

An editor for macOS
Swift
255
star
4

SwiftTreeSitter

Swift API for the tree-sitter incremental parsing system
Swift
236
star
5

Meter

Library for interacting with MetricKit
Swift
210
star
6

OperationPlus

NSOperation's missing pieces
Swift
127
star
7

SwiftLSPClient

A Swift library for interacting with Language Server Protocol implementations
Swift
103
star
8

LanguageClient

Language Server Protocol (LSP) client for Swift
Swift
90
star
9

TextStory

Happier, more flexible NSTextStorage
Swift
86
star
10

Rearrange

Swift library for working with ranges types: NSRange, NSTextRange, Range, UITextRange, and String.Index
Swift
66
star
11

WindowTreatment

Tools for happier work with NSWindow
Swift
61
star
12

LanguageServerProtocol

Swift library for working with Language Server Protocol (LSP)
Swift
56
star
13

ChimeKit

Framework for building Chime extensions
Swift
48
star
14

TextViewPlus

Make life better with NSTextView+TextKit 1/2
Swift
42
star
15

Extendable

A set of utilities for more pleasant work with ExtensionKit
Swift
42
star
16

TextFormation

Rules system for live typing completions
Swift
42
star
17

Wells

A lightweight diagnostics report submission system
Swift
39
star
18

OAuthenticator

OAuth 2.0 request authentication
Swift
39
star
19

ProcessService

Host an executable within an XPC service
Swift
39
star
20

UITestingPlus

Utilities for working with XCUI testing
Swift
38
star
21

NicerTouchBar

Utilities for a more pleasant NSTouchBar development experience
Swift
34
star
22

TextViewBenchmark

A suite of performance tests for macOS text views
Swift
32
star
23

KeyCodes

AppKit Carbon key codes to UIKey-compatible enums
Swift
31
star
24

MeterReporter

Lightweight MetricKit-based diagnostics reporting
Swift
31
star
25

Flexer

Lexing library for Swift
Swift
30
star
26

AsyncXPCConnection

Concurrency support for NSXPCConnection
Swift
30
star
27

JSONRPC

Swift library for JSON-RPC
Swift
24
star
28

ProcessEnv

Capture the shell environment of a Foundation app
Swift
24
star
29

ContainedDocument

Nested NSDocuments
Swift
24
star
30

Dusk

Micro-framework to aid in supporting Dark Mode on macOS
Swift
21
star
31

Glyph

Make life with TextKit better
Swift
21
star
32

ScrollViewPlus

A more pleasant NSScrollView experience
Swift
15
star
33

Welp

Tooling for macOS help books
Swift
15
star
34

XPCConnectionSession

Backwards-compatible implementation of XPCSession
Swift
13
star
35

EditorConfig

A Swift library for working with .editorconfig files
Swift
12
star
36

GlobPattern

Swift package to parse and evaluate glob patterns
Swift
12
star
37

Background

Background Tasks and Networking
Swift
12
star
38

Outline

Lazy SwiftUI wrapper for NSOutlineView
Swift
10
star
39

ImpactMeterAdapter

Impact crash reports as a Meter diagnostic source
Swift
10
star
40

Gramophone

Swift library for working with Extended Backus–Naur Form (EBNF) notation and grammars.
Swift
10
star
41

ViewPlus

Make working with NSView more pleasant
Swift
10
star
42

UnifiedLoggingPlus

Micro-framework for making OSLog more pleasant
Swift
10
star
43

CoreSymbolication

Headers and package for CoreSymbolication
Swift
10
star
44

LanguageServer

Language Server Protocol server infrastructure for Swift
Swift
9
star
45

SwiftCoreSymbolication

Swift wrappers for CoreSymbolication
Swift
9
star
46

chime-swift

A Chime extension for Swift
Swift
9
star
47

DebugAdapterProtocol

Swift library for working with Debug Adapter Protocol (DAP)
Swift
7
star
48

Textbook

Easier NSTextView and SwiftUI
Swift
7
star
49

paddleapi

Go implementation of the Paddle API
Go
6
star
50

SourceView

A TextKit 2 `NSTextView` subclass built specifically to work with source code
Swift
6
star
51

MetricKitViewer

A really simple app for viewing MetricKit payloads
Swift
5
star
52

Ligature

Text selection, grouping, indentation, and manipulation in Swift
Swift
5
star
53

chime-ruby

A Chime extension for Ruby
Swift
4
star
54

ThemePark

A Swift library for working with syntax highlighting/IDE themes
Swift
4
star
55

chime-rust

A Chime extension for Rust
Swift
4
star
56

STTextView-Plugin-TextFormation

Source Code Typing Completions
Swift
4
star
57

RelativeCollections

Swift collection types that support efficient storage of order-relative values.
Swift
4
star
58

Lowlight

A simple syntax processing system that prioritizes latency over correctness
Swift
4
star
59

gogsym

Go library for reading GSYM files
Go
3
star
60

chime-markdown

A Chime extension for Markdown
3
star
61

LanguageServerScripts

A collection of standardized scripts for managing LSP language servers with a Swift API
Shell
3
star
62

chime-elixir

A Chime extension for Elixir
Swift
2
star
63

binarycursor

Go binary data reader
Go
2
star
64

chime-python

A Chime extension for Rust
Swift
2
star
65

chime-go

A Chime extension for Go
Swift
1
star
66

chime-clojure

A Chime extension for Clojure
Swift
1
star
67

marpa-xcframework

XCFramework wrapper for libmarpa
C
1
star
68

Borderline

System for working with text line numbers in Swift
Swift
1
star