• Stars
    star
    137
  • Rank 266,121 (Top 6 %)
  • Language
    Swift
  • License
    MIT License
  • Created almost 3 years ago
  • Updated almost 2 years ago

Reviews

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

Repository Details

Extensions and additions to AsyncSequence, AsyncStream and AsyncThrowingStream.

Asynchrone

Extensions and additions for Swift's async sequence.

Requirements

  • iOS 14.0+
  • macOS 12.0+
  • watchOS 6.0+
  • tvOS 14.0+

Installation

Swift Package Manager

In Xcode:

  1. Click Project.
  2. Click Package Dependencies.
  3. Click +.
  4. Enter package URL: https://github.com/reddavis/Asynchrone.
  5. Add Asynchrone to your app target.

Documentation

Documentation can be found here.

Overview

AsyncSequence

Extensions

Assign

class MyClass {
    var value: Int = 0 {
        didSet { print("Set to \(self.value)") }
    }
}


let sequence = AsyncStream<Int> { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.finish()
}

let object = MyClass()
sequence.assign(to: \.value, on: object)

// Prints:
// Set to 1
// Set to 2
// Set to 3

First

let sequence = AsyncStream<Int> { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.finish()
}

print(await sequence.first())

// Prints:
// 1

Last

let sequence = AsyncStream<Int> { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.finish()
}

print(await sequence.last())

// Prints:
// 3

Collect

let sequence = AsyncStream<Int> { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.finish()
}

print(await sequence.collect())

// Prints:
// [1, 2, 3]

Sink

let sequence = .init { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.finish()
}

sequence.sink { print($0) }

// Prints:
// 1
// 2
// 3

Sink with completion

let sequence = .init { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.finish(throwing: TestError())
}

sequence.sink(
    receiveValue: { print("Value: \($0)") },
    receiveCompletion: { print("Complete: \($0)") }
)

// Prints:
// Value: 1
// Value: 2
// Value: 3
// Complete: failure(TestError())

AnyAsyncSequenceable

let sequence = Just(1)
    .map(String.init)
    .eraseToAnyAsyncSequenceable()

AnyThrowingAsyncSequenceable

let stream = Fail<Int, TestError>(error: TestError.a)
    .eraseToAnyThrowingAsyncSequenceable()

CatchErrorAsyncSequence

let sequence = Fail<Int, TestError>(
    error: TestError()
)
.catch { error in
    Just(-1)
}

for await value in sequence {
    print(value)
}

// Prints:
// -1

ChainAsyncSequence

let sequenceA = AsyncStream<Int> { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.finish()
}

let sequenceB = AsyncStream<Int> { continuation in
    continuation.yield(4)
    continuation.yield(5)
    continuation.yield(6)
    continuation.finish()
}

let sequenceC = AsyncStream<Int> { continuation in
    continuation.yield(7)
    continuation.yield(8)
    continuation.yield(9)
    continuation.finish()
}

for await value in sequenceA.chain(with: sequenceB).chain(with: sequenceC) {
    print(value)
}

// Prints:
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

CombineLatestAsyncSequence

let streamA = .init { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.yield(4)
    continuation.finish()
}

let streamB = .init { continuation in
    continuation.yield(5)
    continuation.yield(6)
    continuation.yield(7)
    continuation.yield(8)
    continuation.yield(9)
    continuation.finish()
}

for await value in streamA.combineLatest(streamB) {
    print(value)
}

// Prints:
// (1, 5)
// (2, 6)
// (3, 7)
// (4, 8)
// (4, 9)

CombineLatest3AsyncSequence

let streamA = .init { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.yield(4)
    continuation.finish()
}

let streamB = .init { continuation in
    continuation.yield(5)
    continuation.yield(6)
    continuation.yield(7)
    continuation.yield(8)
    continuation.yield(9)
    continuation.finish()
}

let streamC = .init { continuation in
    continuation.yield(10)
    continuation.yield(11)
    continuation.finish()
}

for await value in streamA.combineLatest(streamB, streamC) {
    print(value)
}

// Prints:
// (1, 5, 10)
// (2, 6, 11)
// (3, 7, 11)
// (4, 8, 11)
// (4, 9, 11)

CurrentElementAsyncSequence

let sequence = CurrentElementAsyncSequence(0)
print(await sequence.element)

await stream.yield(1)
print(await sequence.element)

await stream.yield(2)
await stream.yield(3)
await stream.yield(4)
print(await sequence.element)

// Prints:
// 0
// 1
// 4

DebounceAsyncSequence

let stream = AsyncStream<Int> { continuation in
    continuation.yield(0)
    try? await Task.sleep(nanoseconds: 200_000_000)
    continuation.yield(1)
    try? await Task.sleep(nanoseconds: 200_000_000)
    continuation.yield(2)
    continuation.yield(3)
    continuation.yield(4)
    continuation.yield(5)
    continuation.finish()
}

for element in try await self.stream.debounce(for: 0.1) {
    print(element)
}

// Prints:
// 0
// 1
// 5

DelayAsyncSequence

let stream = AsyncStream<Int> { continuation in
    continuation.yield(0)
    continuation.yield(1)
    continuation.yield(2)
    continuation.finish()
}

let start = Date.now
for element in try await self.stream.delay(for: 0.5) {
    print("\(element) - \(Date.now.timeIntervalSince(start))")
}

// Prints:
// 0 - 0.5
// 1 - 1.0
// 2 - 1.5
>>>>>>> main

Empty

Empty<Int>().sink(
    receiveValue: { print($0) },
    receiveCompletion: { completion in
        switch completion {
        case .finished:
            print("Finished")
        case .failure:
            print("Failed")
        }
    }
)

// Prints:
// Finished

Fail

let stream = Fail<Int, TestError>(error: TestError())

do {
    for try await value in stream {
        print(value)
    }
} catch {
    print("Error!")
}

// Prints:
// Error!

Just

let stream = Just(1)

for await value in stream {
    print(value)
}

// Prints:
// 1

MergeAsyncSequence

let streamA = .init { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.yield(4)
    continuation.finish()
}

let streamB = .init { continuation in
    continuation.yield(5)
    continuation.yield(6)
    continuation.yield(7)
    continuation.yield(8)
    continuation.yield(9)
    continuation.finish()
}

for await value in streamA.merge(with: streamB) {
    print(value)
}

// Prints:
// 1
// 5
// 2
// 6
// 3
// 7
// 4
// 8
// 9

Merge3AsyncSequence

let streamA = .init { continuation in
    continuation.yield(1)
    continuation.yield(4)
    continuation.finish()
}

let streamB = .init { continuation in
    continuation.yield(2)
    continuation.finish()
}

let streamC = .init { continuation in
    continuation.yield(3)
    continuation.finish()
}

for await value in self.streamA.merge(with: self.streamB, self.streamC) {
    print(value)
}

// Prints:
// 1
// 2
// 3
// 4

NotificationCenterAsyncSequence

let sequence = NotificationCenter.default.sequence(for: UIDevice.orientationDidChangeNotification)

for await element in sequence {
    print(element)
}

PassthroughAsyncSequence

let sequence = PassthroughAsyncSequence<Int>()
sequence.yield(0)
sequence.yield(1)
sequence.yield(2)
sequence.finish()

for await value in sequence {
    print(value)
}

// Prints:
// 0
// 1
// 2

RemoveDuplicatesAsyncSequence

let stream = .init { continuation in
    continuation.yield(1)
    continuation.yield(1)
    continuation.yield(2)
    continuation.yield(3)
    continuation.finish()
}

for await value in stream.removeDuplicates() {
    print(value)
}

// Prints:
// 1
// 2
// 3

ReplaceErrorAsyncSequence

let sequence = Fail<Int, TestError>(
    error: TestError()
)
.replaceError(with: 0)

for await value in stream {
    print(value)
}

// Prints:
// 0

SequenceAsyncSequence

let sequence = [0, 1, 2, 3].async

for await value in sequence {
    print(value)
}

// Prints:
// 1
// 2
// 3

SharedAsyncSequence

let values = [
    "a",
    "ab",
    "abc",
    "abcd"
]

let stream = AsyncStream { continuation in
    for value in values {
        continuation.yield(value)
    }
    continuation.finish()
}
.shared()

Task {
    let values = try await self.stream.collect()
    // ...
}

Task.detached {
    let values = try await self.stream.collect()
    // ...
}

let values = try await self.stream.collect()
// ...

ThrottleAsyncSequence

let stream = AsyncStream<Int> { continuation in
    continuation.yield(0)
    try? await Task.sleep(nanoseconds: 100_000_000)
    continuation.yield(1)
    try? await Task.sleep(nanoseconds: 100_000_000)
    continuation.yield(2)
    continuation.yield(3)
    continuation.yield(4)
    continuation.yield(5)
    continuation.finish()
}

for element in try await self.stream.throttle(for: 0.05, latest: true) {
    print(element)
}

// Prints:
// 0
// 1
// 2
// 5

ThrowingPassthroughAsyncSequence

let sequence = ThrowingPassthroughAsyncSequence<Int>()
sequence.yield(0)
sequence.yield(1)
sequence.yield(2)
sequence.finish(throwing: TestError())

do {
    for try await value in sequence {
      print(value)
    }
} catch {
    print("Error!")
}

// Prints:
// 0
// 1
// 2
// Error!

TimerAsyncSequence

let sequence = TimerAsyncSequence(interval: 1)

let start = Date.now
for element in await sequence {
    print(element)
}

// Prints:
// 2022-03-19 20:49:30 +0000
// 2022-03-19 20:49:31 +0000
// 2022-03-19 20:49:32 +0000

ZipAsyncSequence

let streamA = .init { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.finish()
}

let streamB = .init { continuation in
    continuation.yield(5)
    continuation.yield(6)
    continuation.yield(7)
    continuation.finish()
}

for await value in streamA.zip(streamB) {
    print(value)
}

// Prints:
// (1, 5)
// (2, 6)

Zip3AsyncSequence

let streamA = .init { continuation in
    continuation.yield(1)
    continuation.yield(2)
    continuation.finish()
}

let streamB = .init { continuation in
    continuation.yield(5)
    continuation.yield(6)
    continuation.yield(7)
    continuation.finish()
}

let streamC = .init { continuation in
    continuation.yield(8)
    continuation.yield(9)
    continuation.finish()
}

for await value in streamA.zip(streamB, streamC) {
    print(value)
}

// Prints:
// (1, 5, 8)
// (2, 6, 9)

Other libraries

  • Papyrus - Papyrus aims to hit the sweet spot between saving raw API responses to the file system and a fully fledged database like Realm.
  • Validate - A property wrapper that can validate the property it wraps.
  • Kyu - A persistent queue system in Swift.
  • FloatingLabelTextFieldStyle - A floating label style for SwiftUI's TextField.
  • Panel - A panel component similar to the iOS Airpod battery panel.

More Repositories

1

RDActionSheet

Class to make a easily customisable Action Sheet for iOS
Objective-C
186
star
2

K-Means

K Means
Ruby
115
star
3

freelancer-tools

List of useful tools for freelancers
81
star
4

REDActionSheet

Tweetbot action sheet
Objective-C
51
star
5

Naive-Bayes

Simple Naive Bayes classifier
Ruby
47
star
6

Crypto-Icons-API

API for crypto icons
HTML
41
star
7

knn

Simple K Nearest Neighbour Algorithm
Ruby
37
star
8

N-Gram

N-Gram generator in Ruby - http://en.wikipedia.org/wiki/N-gram
Ruby
36
star
9

TF-IDF

Term Frequency - Inverse Document Frequency in Ruby
Ruby
35
star
10

Distance-Measures

A bunch of distance measures
Ruby
31
star
11

Papyrus

Papyrus aims to hit the sweet spot between saving raw API responses to the file system and a fully fledged database like Realm.
Swift
25
star
12

Tweaker

Experiment!
Swift
21
star
13

Stripe-CardIO

Mixing Stripe and CardIO
Objective-C
21
star
14

REDPuzzleGridView

A word puzzle control, similar to Ruzzle's letter board
Objective-C
20
star
15

REDRangeSlider

Range Slider for iOS
Objective-C
19
star
16

FloatingLabelTextFieldStyle

A floating label style for SwiftUI's TextField.
Swift
16
star
17

Panel

A SwiftUI panel component similar to the iOS Airpod battery panel or the Share Wi-Fi password panel.
Swift
15
star
18

embedit

Embed media easily into your site
Ruby
14
star
19

RedUx

A super simple Swift implementation of the redux pattern making use of Swift 5.5's new async await API's.
Swift
14
star
20

Le-Code

OSX Player for the Spotify playlist "Le Code"
Objective-C
13
star
21

Campfire-Bot

Bots in your Campfires!
Ruby
13
star
22

mlp

Multi-Layer Perceptron Neural Network in Ruby
Ruby
12
star
23

rubytorrent

Port of RubyTorrent from svn
11
star
24

arrrpi_gem_builder

Turn API documentation into a wrapper
Ruby
10
star
25

Nanoleaf

Swift API client for Nanoleaf smart lights.
Swift
9
star
26

SOM

A Self Organising Map
Ruby
8
star
27

panda_cap

Capistrano recipe for Panda and MySql
Ruby
8
star
28

Date-Formatter

A little app to help with NSDateFormmater date formats
Objective-C
8
star
29

NLP-Backpack

An NLP playground
Ruby
7
star
30

Clickatell

Wrapper for http://clickatell.com
Ruby
7
star
31

CryptoIconURLBuilder

Swift
7
star
32

Spotify-Queue

Spotify play queue manager for the office
Objective-C
6
star
33

RDNotification

This class is a simple, non-instrusive alert view
Objective-C
6
star
34

ApacheBench-GUI

GUI on top of ApacheBench
Objective-C
5
star
35

i-created-something-cool

An app for all your cool apps
Ruby
5
star
36

knn_c

Knn ruby C extension
Ruby
5
star
37

Coinbase

Coinbase Swift SDK
Swift
5
star
38

REDAlertView

Experimental UIAlertView kinda thing
Objective-C
4
star
39

dbmlp

Database back Neural Network
Ruby
4
star
40

Feature-Selection

A library of feature selection algorithms.
Ruby
4
star
41

One40Proof

http://developers.140proof.com/docs/
Ruby
4
star
42

Puts-Finder

Find your lost puts
Ruby
4
star
43

Part-Of-Speech

Part of speech tagger
Ruby
4
star
44

Embedit-Gem

Wrapper for http://embedit.me
Ruby
3
star
45

is-monday-ok-

Arrange a meetup
3
star
46

Validate

A property wrapper that can validate the property it wraps.
Swift
3
star
47

TableData

Table Data is super flexible framework for building complicated table views.
Swift
3
star
48

Lumi

Swift
3
star
49

CSVDecoder

A Swift CSV decoder
Swift
3
star
50

poker

http://acm.uva.es/p/v103/10315.html
Ruby
3
star
51

panda-mysql-and-activerecord

Panda + Activerecord
3
star
52

Changelly

Changelly Swift SDK
Swift
2
star
53

Hue-Experiment

iPhone + TV + Hue
Objective-C
2
star
54

REDHTTPLogger

REDHTTPLogger makes it easy to inspect HTTP requests happening inside your iOS app without needed the debugger attached.
Objective-C
2
star
55

CV

My CV
Ruby
2
star
56

puzzles

http://www.facebook.com/careers/puzzles.php
2
star
57

robotnik

Tool for merging and compressing stylesheets and javascript files
Ruby
2
star
58

Noun-Phrase-Detection

Basic noun phrase detection
Ruby
2
star
59

Objective-Stripe

Objective C wrapper for Stripe API
Objective-C
2
star
60

Data-Prep

Helps you prepare your data for machine learning
Ruby
2
star
61

SegmentedControl

Swift
2
star
62

Nest-Dehumidifier

Ruby
2
star
63

Frequency-Distribution

http://en.wikipedia.org/wiki/Frequency_distribution
Ruby
2
star
64

Project-Euler

Problems from http://projecteuler.net
1
star
65

Test

Dummy repo for an app
1
star
66

showerthoughts-screensaver

macOS screensaver for r/showerthoughts
Swift
1
star
67

Toolbox

Just a collection of random extensions I use.
Swift
1
star
68

Magick-Identify

Wrapper around Image Magicks cl "identify"
1
star
69

Benchmarker

Instant benchmark feedback
Ruby
1
star
70

Proposal-Template

Template for my freelancing proposal
1
star
71

Arrrpi-Twitter

A Twitter wrapper generated using the arrrpi gem builder
Ruby
1
star
72

REDModel

Simple NSUserDefaults wrapper
Objective-C
1
star
73

zync

Ruby
1
star
74

Normalizer

Tool for normalizing data
Ruby
1
star
75

Bitly

Bitly
Ruby
1
star
76

doing_some_c

Trying out C
C
1
star
77

HTTP

Just some code I use for communicating and parsing API's.
Swift
1
star
78

Binary-Tree

Monkey down the binary tree
C
1
star