Swift Async Algorithms is an open-source package of asynchronous sequence and advanced algorithms that involve concurrency, along with their related types.
This package has three main goals:
- First-class integration with
- Provide a home for time-based algorithms
- Be cross-platform and open source
AsyncAlgorithms is a package for algorithms that work with values over time. That includes those primarily about time, like
throttle, but also algorithms about order like
merge. Operations that work with multiple inputs (like
zip does on
Sequence) can be surprisingly complex to implement, with subtle behaviors and many edge cases to consider. A shared package can get these details correct, with extensive testing and documentation, for the benefit of all Swift apps.
The foundation for AsyncAlgorithms was included in Swift 5.5 from AsyncSequence. Swift 5.5 also brings the ability to use a natural
for/in loop with
await to process the values in an
Sequence-equivalent API like
filter. Structured concurrency allows us to write code where intermediate state is simply a local variable,
try can be used directly on functions that
throw, and generally treat the logic for asynchronous code similar to that of synchronous code.
Combining asynchronous sequences
chain(_:...): Concatenates two or more asynchronous sequences with the same element type.
combineLatest(_:...): Combines two or more asynchronous sequences into an asynchronous sequence producing a tuple of elements from those base asynchronous sequences that updates when any of the base sequences produce a value.
merge(_:...): Merges two or more asynchronous sequence into a single asynchronous sequence producing the elements of all of the underlying asynchronous sequences.
zip(_:...): Creates an asynchronous sequence of pairs built out of underlying asynchronous sequences.
joined(separator:): Concatenated elements of an asynchronous sequence of asynchronous sequences, inserting the given separator between each element.
Creating asynchronous sequences
async: Create an asynchronous sequence composed from a synchronous sequence.
AsyncChannel: An asynchronous sequence with back pressure sending semantics.
AsyncThrowingChannel: An asynchronous sequence with back pressure sending semantics that can emit failures.
Performance optimized asynchronous iterators
AsyncBufferedByteIterator: A highly efficient iterator useful for iterating byte sequences derived from asynchronous read functions.
Other useful asynchronous sequences
chunked(...): Collect values into chunks.
compacted(): Remove nil values from an asynchronous sequence.
removeDuplicates(): Remove sequentially adjacent duplicate values.
interspersed(with:): Place a value between every two elements of an asynchronous sequence.
Asynchronous Sequences that transact in time
debounce(for:tolerance:clock:): Emit values after a quiessence period has been reached.
throttle(for:clock:reducing:): Ensure a minimum interval has elapsed between events.
AsyncTimerSequence: Emit the value of now at a given interval repeatedly.
Obtaining all values from an asynchronous sequence
RangeReplaceableCollection.init(_:): Creates a new instance of a collection containing the elements of an asynchronous sequence.
Dictionary.init(uniqueKeysWithValues:): Creates a new dictionary from the key-value pairs in the given asynchronous sequence.
Dictionary.init(_:uniquingKeysWith:): Creates a new dictionary from the key-value pairs in the given asynchronous sequence, using a combining closure to determine the value for any duplicate keys.
Dictionary.init(grouping:by:): /// Creates a new dictionary whose keys are the groupings returned by the given closure and whose values are arrays of the elements that returned each key.
SetAlgebra.init(_:): Creates a new set from an asynchronous sequence of items.
Task.select(_:): Determine the first task to complete of a sequence of tasks.
Each algorithm has specific behavioral effects. For throwing effects these can either be if the sequence throws, does not throw, or rethrows errors. Sendability effects in some asynchronous sequences are conditional whereas others require the composed parts to all be sendable to satisfy a requirement of
Sendable. The effects are listed here.
Mobile App Development Best Practices – 04.10
iOS New and Deprecated APIs in iOS 17 Abstract Class vs. Protocol-Oriented Approach in Swift Comparing the Performance of the...
New and Deprecated APIs in iOS 17
In this video, I would like to share with you some things that were either deprecated or added in iOS...
Promova helps people with dyslexia learn languages
The new Promova feature comes just in time for National Dyslexia Awareness Month and is available on the platform for...
Notify – A simple note application with modern MVVM, Compose and Material3
Notify is a simple note application that is built with Modern Android development tools. This project showcases the Good implementation...
Mobile App Development Best Practices – 03.10
iOS MetaCodable – Supercharge Swift’s Codable implementations with macros meta-programming How to build a Tuist plugin and publish it using...
How to make and use BOM (Bill of Materials) dependencies in Android projects
By using a BOM dependency, you can avoid specifying the versions of each individual library in your app, and let...