Skip to content

Pimine/Swift-Macros-AddAsync-example

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AddAsync

Swift Platform License

AddAsync is a Swift Macro that automatically generates async/await versions of your legacy completion-handler functions.

Stop writing boilerplate withCheckedContinuation wrappers manually. Let the compiler do it for you safely and cleanly.

Features

  • Zero Runtime Overhead: All code is generated at compile time.
  • Protocol Support: Works on protocol definitions (generates async signatures without bodies).
  • Smart Detection: Automatically detects if the function should throw errors (for Result types) or just return values.
  • Generic Support: Works perfectly with <T: Model>, arrays [T], and complex signatures.

Installation

Xcode (SPM)

  1. Go to File > Add Package Dependencies...
  2. Enter the URL of your repository:
    https://github.com/theLastOrbit/swift-macros-AddAsync.git
    
  3. Click Add Package.

Package.swift

Add it to your dependencies in Package.swift:

dependencies: [
    .package(url: "https://github.com/theLastOrbit/swift-macros-AddAsync.git", from: "1.1.0")
]

Then add "AddAsync" to your target's dependencies.


Usage

Simply attach @AddAsync to any function that accepts a completion handler as its last parameter.

1. Result Types (Async + Throws)

If your completion handler returns a Result<T, Error>, the generated function will be async throws and return the success type T.

Code:

import AddAsync

@AddAsync
func fetchUser(id: String, completion: @escaping (Result<User, Error>) -> Void) {
    // Legacy code logic...
}

Generated Peer Function (Invisible):

func fetchUser(id: String) async throws -> User {
    return try await withCheckedThrowingContinuation { continuation in
        fetchUser(id: id) { result in
            continuation.resume(with: result)
        }
    }
}

2. Protocols (Signatures Only)

You can use @AddAsync in protocols. It will generate the async requirement signature automatically.

Code:

protocol NetworkService {
    @AddAsync
    func fetchConfig(completion: @escaping (Result<Config, Error>) -> Void)
}

Generated Requirement (Invisible):

protocol NetworkService {
    func fetchConfig(completion: @escaping (Result<Config, Error>) -> Void)

    // Generated:
    func fetchConfig() async throws -> Config
}

3. Generics & Optionals

If your completion handler returns a standard value (like T? or [T]?), the generated function will be async (non-throwing) and preserve all generic constraints.

Code:

@AddAsync
func fetch<T: Model>(with router: BaseRouter, completion: @escaping (T?) -> Void) {
    // Legacy code logic...
}

Generated Peer Function (Invisible):

func fetch<T: Model>(with router: BaseRouter) async -> T? {
    return await withCheckedContinuation { continuation in
        fetch(with: router) { value in
            continuation.resume(returning: value)
        }
    }
}

Requirements

  • Swift 5.9+ (Xcode 15+)
  • iOS 13.0+ / macOS 10.15+ (Backward compatible runtime)

License

This library is released under the MIT License. See LICENSE for details.

Inspiration: Got the inspiration to make this library:

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Swift 100.0%