Swiftpack.co - Henryforce/AsyncTimeSequences as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by Henryforce.
Henryforce/AsyncTimeSequences v0.0.7
The missing Time-Sequence-Operators for Swift Concurrency
⭐️ 1
🕓 4 days ago
iOS macOS watchOS tvOS
.package(url: "https://github.com/Henryforce/AsyncTimeSequences.git", from: "v0.0.7")

AsyncTimeSequences

badge-platforms badge-spm

This is a convenient package to add missing time async sequences such as debounce, throttle, delay, timeout and measure interval.

These sequences are recommended to be used with AsyncStreams, but as they conform to the AsyncSequence Protocol the possibilities are endless.

Compatibility

This package is supported on Xcode 13.2+ targeting iOS 13+, MacOS 10.15+, WatchOS 6+ and TvOS 13+.

How to use

For all examples, please first consider this sample sequence (remember that you can use any Async Sequence):

let asyncSequence = AsyncStream { (continuation:AsyncStream<Int>.Continuation) in
    Task {
        let items = [1,2,3,4,5,6]
        for item in items {
            continuation.yield(item)
            try? await Task.sleep(nanoseconds: 1000000)
        }
        continuation.finish()
    }
}

All the async sequences will need an async scheduler. For convenience, there is one already bundled with this package. You should be good with the main one provided. But you are free to add your custom one if required (by conforming to the AsyncScheduler protocol).

Timeout

asyncSequence.timeout(for: 2, scheduler: MainAsyncScheduler.default)

Delay

asyncSequence.delay(for: 3, scheduler: MainAsyncScheduler.default)

Debounce

asyncSequence.debounce(for: 3, scheduler: MainAsyncScheduler.default)

Throttle

asyncSequence.throttle(for: 3, scheduler: MainAsyncScheduler.default, latest: true)

MeasureInterval

asyncSequence.measureInterval(using: MainAsyncScheduler.default)

How to test

Properly testing time sequences requires some setup. Ideally, it is recommended to inject the scheduler, that will execute the time handling of your sequences, into your logic object.

By injecting the scheduler, you can for example inject a test scheduler to manipulate the time operators.

It is recommended to use the TestAsyncScheduler included in the AsyncTimeSequencesSupport sub-package. It has a really convenient function to manipulate time:

let scheduler = AsyncTestScheduler()
scheduler.advance(by: 3.0) // Advances the time virtually and executes scheduled jobs immediately without actually waiting the time interval specified

An example on how to inject the schduler if you have a view model:

final class MyViewModel {

    private let scheduler: AsyncScheduler

    init(
        scheduler: AsyncScheduler = MainAsyncScheduler.default // Allow injection while providing a default scheduler
    ) {
        self.scheduler = scheduler
    }
    
    func debounceSequence<T: AsyncSequence>(_ sequence: T) {
        let debounceSequence = sequence.debounce(for: 3.0, scheduler: scheduler)
        
        Task {
            for await value in debounceSequence {
                // do something that produces an output which can be evaluated and asserted during testing...
            }
        }
    }

}
import AsyncTimeSequences
import AsyncTimeSequencesSupport

...

func testAsyncDebounceSequence() async {
    // Given
    let scheduler = TestAsyncScheduler()
    let viewModel = MyViewModel(scheduler: scheduler)
    let items = [1,5,10,15,20]
    let expectedItems = [20]
    let baseDelay = 3.0
    var receivedItems = [Int](https://raw.github.com/Henryforce/AsyncTimeSequences/main/)
    
    // When
    let sequence = ControlledDataSequence(items: items)
    viewModel.debounceSequence()

    // If we don't wait for jobs to get scheduled, advancing the scheduler does virtually nothing...
    await sequence.iterator.waitForItemsToBeSent(items.count)
    await scheduler.advance(by: baseDelay)
    
    // your code to process the view model output...
}

If you need further code examples, you can take a look at the tests for this package library. They rely heavily on the AsyncTestScheduler and the ControlledDataSequence classes, which are included in the AsyncTimeSequencesSupport sub-package.

Installation

Swift Package Manager

In Xcode, select File --> Swift Packages --> Add Package Dependency and then add the following url:

https://github.com/Henryforce/AsyncTimeSequences

There are two package included:

  • AsyncTimeSequences - async time sequences extensions
  • AsyncTimeSequencesSupport - async time sequences support classes for testing. (Recommended to include only in your test targets)

GitHub

link
Stars: 1
Last commit: 4 days ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics