/Swift-Macros

A curated list of awesome Swift Macros

Primary LanguageSwiftMIT LicenseMIT

Swift Macros 🚀



Swift Macros have brought in a new wave of possibilities. The aim of this project is to curate a list of community-created Macros and associated learning resources.

A lot of use-cases my Sourcery covered before can now be implemented by Swift Macros.






Learning Resources 📚

Tools

Frameworks

  • Swift Macro Testing: Magical testing tools for Swift macros.
    • Provides assertMacro, an alternative to Apple's assertMacroExpansion that automatically snapshots macro expansions.
    • Also provides string-based matching for diagnostics and fix-its instead of manually specifying line and column numbers.
  • Macro ToolKit
    • A powerful toolkit for creating concise and expressive Swift macros.

Apple:

Dive into Swift Macros with these WWDC sessions:

  • Write Swift Macros: An introductory session on Macros, their roles, and workings with a basic example.
  • Expand Swift Macros: A deeper exploration into crafting your Macros and testing their functionality.

Other Apple Resources:

  • Macros: The Official Step-by-Step Guide to Using Macros for Compile-Time Code Generation in Swift.
  • Example Swift Macros: Check out real-world examples from Apple, like @AddCompletionHandler and @AddAsync.

Community Blogs


Macros 💻

SwiftUI

  • EnvironmentValues & EnvironmentValue: Bypass boilerplate code and swiftly support new SwiftUI Environment Keys and Values.
  • SFSymbols Macro: A Swift Macro for "type-safe" SF Symbols.
  • SF Symbols Generator: A Swift macro generating type-safe SF Symbols.
  • Prototype (WIP): Prototype generates SwiftUI Forms and Views for data structures and classes, designed to complement SwiftData Models seamlessly.
  • HexColors: Swift Macros for validating hex colors from string and hexadecimal integer literals.

Models

  • Coding Keys: Effortlessly generate CodingKeys for converting snake_case to lowerCamelCase.
  • Coding Keys: A Swift Macro for automating CodingKeys creation in Codable structs. Supports custom string mappings for properties.
  • Coding Keys: Swift macros generating customizable CodingKeys.
  • Builder pattern: Apply the Builder Pattern with ease by generating a Builder helper class, mimicking stored properties of the associated struct.
  • Struct Builder Macro: An attached macro that produces a peer struct which implements the builder pattern. This allows the creation of the struct with minimal effort using default values.
  • EnhancedMirror: An experimental Mirror alternative that utilizes Swift Macros for static reflection.
  • MetaCodable: Generates Codable implementation with following features:
    • Allows custom CodingKey value declaration per variable, instead of requiring you to write for all fields.
    • Allows to create flattened model for nested CodingKey values.
    • Allows to create composition of multiple Codable types.
    • Allows to provide default value in case of decoding failures.
    • Generates member-wise initializer considering the default values.
    • Allows to create custom decoding/encoding strategies.
  • Sealed: Parsing easily Sealed Class JSON Model on Server. (ex. kotlin server)
  • MacroCodableKit: Fully self-sufficient Codable kit:
    • Implements OpenAPI allOf and oneOf specs
    • Adjusts coding keys with a simple @CodingKey annotation
    • Decodes arrays and dictionaries in a safe manner with @CustomCoding(SafeDecoding)
    • Has built-in per-property Codable strategies and is extendible for new ones.
  • SampleBuilder: The aim of @SampleBuilder is straightforward: Generate an array of sample data from your models for use in SwiftUI previews, unit tests, or any scenario that needs mock data—without the hassle of crafting it from scratch.It works with structs and enums!
    • SampleBuilderItem: If you want to customize your sample data even further for .random generator, you can use @SampleBuilderItem to specify the type of data you want to generate for each property in your model (images, prices, names, etc.).

Dependency Injection

  • swift-blade: A macro powered dependency injection framework.
  • MDI: High performance dependency injection framework.

Testing

  • Power Assert: Adds assertions that can automatically produce information about the values being evaluated, and present it in an easily digestible form.
  • Spyable: A Swift macro that simplifies and automates the process of creating spies for testing. Using the @Spyable annotation on a protocol, the macro generates a spy class that implements the same interface as the protocol and keeps track of interactions with its methods and properties.
  • SwiftMock: A Swift framework that simplifies and automates the process of creating mock objects for testing. Using the @Mock macro on a protocol generates Mock class. You can stub methods and properties, verifying mock calls.
  • XCTestParametrizedMacro: A Swift macro that greatly simplifies testing for many parameters. It will allow you to write one test method and parametrize it with many cases. Use @Parametrize(input: ["any", "values"]) to automatically generate new test methods for all parameters.

Networking

  • SwiftRequest: SwiftRequest is a lightweight, type-safe HTTP client for Swift, streamlining the construction and execution of HTTP request build on top of Macros.
  • Papyrus: A type-safe, protocol based HTTP client - turn your APIs into Swift protocols. Includes first-class testing support with out of the box mocking.

Enums

  • ExtractCaseValue: A Swift macro that extracts associated values from enum cases.

Misc

  • MacroKit: A collection of macros including:
    • @PublicInit: Generate public memberwise init
    • @GenerateMock: Create a mock object for testing from a protocol
    • @KeyPathIterable: Like CaseIterable but for available keypaths on a type
    • @StaticMemberIterable: Like CaseIterable but for available static members on a type
    • More to come...
  • InitMacro: A Swift Macro implementation that generates initializers for classes and structs with support for default values, wildcards and access control.
  • AssociatedObject: A Swift Macro for adding stored properties in Extension to classes defined in external modules, etc.
    (This is implemented by wrapping objc_getAssociatedObject/objc_setAssociatedObject.)
  • AssociatedObjectMacro: A Swift Macro for convenient declaration of variables in class extensions.
  • AliasMacro: A Swift Macro for defining aliases for types, functions, or variables.
  • UtilityType: UtilityType is an innovative library designed to realize TypeScript's UtilityTypes in Swift. See more details: https://www.typescriptlang.org/docs/handbook/utility-types.html
    • @Partial,@Required: Constructs a type with all properties set to optional(@Partial) or require(@Required). This utility will return a type that represents all subsets of a given type.
    • @Pick,@Omit: Constructs a type by picking(@Pick) or removing(@Omit) the set of specific properties keys (only string literal) from attached Type.
    • @Exclude,@Extract: Constructs a type by excluding(@Exclude) or extracting(@Extract) from enum all cases.
    • @Parameters: Constructs a tuple type from the types used in the parameters of a function type.
    • @ReturnType: Constructs a type consisting of the return type of function.
  • Reuse Identifier: A Reuse Identifier Macro that is useful in generation of a reuse id for your UICollectionViewCells and UITableViewCells
  • SwiftMacros collection: A practical collection of Swift Macros that help code correctly and smartly.
  • ModifiedCopyMacro: A Swift macro for making inline copies of a struct by modifying a property.
  • DictionaryLiteralShorthandMacro: A Swfit macro for creating dictionary literals with keys as "string representations of corresponding variable names".
  • TemporaryVariable: TemporaryVariable provide a macro #info {...}. It capture most function calls and assign them to temporary variables.
  • Localizable: Localizable A macro that produces variables and methods, for your localization files. From the enumeration keys.
  • SafeDecoding: SafeDecoding A macro that implements failable decoding via custom initializer; allows auto-conformance to `Decodable`` and per-property opt-out.
  • ObfuscateMacro: A macro for obfuscating strings and make them harder to find by binary analysis.
  • MemberwiseInit: Informed by explicit developer cues, @MemberwiseInit can more often automatically provide your intended memberwise init, while following the same safe-by-default semantics underlying Swift’s memberwise initializers.
  • PropertyTracer: Library for tracing access to properties.@PropertyTraced macro makes possible to trace from which method a property has been accessed.

Take part in this exciting evolution in Swift. Your contributions are most welcome!