Awesome
Swift Macros :rocket:
<img align="left" width="256" height="256" src="https://github.com/krzysztofzablocki/Swift-Macros/blob/d218dea43b205e1c002feb28610d58d2c4d105dc/Icon.png"> </br></br>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.
<br/><br/><br/><br/><br/>
Learning Resources :books:
Tools
- Swift AST Explorer
- This is extremely helpful when working with SwiftSyntax, I used this when writing Sourcery parser and you can leverage it to build your own Macros.
Frameworks
- Swift Macro Testing: Magical testing tools for Swift macros.
- Provides
assertMacro
, an alternative to Apple'sassertMacroExpansion
that automatically snapshots macro expansions. - Also provides string-based matching for diagnostics and fix-its instead of manually specifying line and column numbers.
- Provides
- 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
- Swift Macros by SwiftLee
- Antoine goes over the introduction of what Macros are and how you can build your own one with an example.
- How to Create Swift Macros in Xcode 15
- Francesco goes over creating your first macro with testing and some interesting tidbits.
- Exploring Swift Macros
- Sergey goes over creating a macro for a memberwise initaliser step by step with tests and convenience methods for SwiftSyntax
- Automating RawRepresentable Conformance with Swift Macros
- Nikita goes over creating a macro for automating the String RawRepresentable conformance.
- Setup to develop Swift Macros
- A step-by-step tutorial to develop Swift Macros.
- Support Swift macros with CocoaPods
- Guide to distribute your macros using CocoaPods.
- Deep Dive Into Macros by Coding With Vera
- Vera goes into how Macros work with a real-life comparison. Also explains the different types of macros and how they can help your codebase.
Macros :computer:
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
tolowerCamelCase
. - 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. - Buildable Macro: An attached macro for structs, classes and enums, which produces a peer struct implementing the builder pattern. Initialise your object with minimal effort using default values:
@Buildable struct Person { ... } let person = PersonBuilder(age: 42).build()
- 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.
- Allows specifying fallback
CodingKey
values for fields and cases. - Allows to ignore specific properties/cases from decoding/encoding.
- Allows setting
CodingKey
case style per type. - Allows decoding/encoding any type that conform to a particular protocol.
- Allows decoding/encoding enums and protocols with external/internal/adjacent identifier.
- Allows decoding/encoding enums and protocols with non-
String
identifier or customize the identifier detection.
- Allows custom
- Sealed: Parsing easily Sealed Class JSON Model on Server. (ex. kotlin server)
- MacroCodableKit: Fully self-sufficient
Codable
kit: - 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
andenums
!- 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.).
- SampleBuilderItem: If you want to customize your sample data even further for
- CodableOptionSet: CodableOptionSet allows for easy extensions to OptionSets implementing Codable protocol.
- ListableProperties: ListableProperties macro adds
getProperties
static func which returns an array of all property names in your model. - BuildableMacro: A set of macros simplifying setter function generation for nominal types, inspired by SwiftUI modifiers and Observation framework macros:
@Buildable
Automates the marking of settable properties as@BuildableTracked
, excluding those marked as@BuildableIgnored
.@BuildableTracked
Generates setter functions for each marked property, allowing fluent chaining of modifications.@BuildableIgnored
Excludes properties from automatic setter function generation.
- StaticArray: An allocation-less C-like fixed size arrays.
- UserDefaultsObservation: Combines UserDefaults and the Observation Framework. Users can easily create an Observable class where properties are backed by UserDefaults and NSUbiquitousKeyValueStore.
- LoremSwiftify: LoremSwiftify is a Macro that creates lorem ipsum data for your models.
- SwiftCopyable: Auto-generates a
copy
function for structs, making it easy to duplicate a struct instance while updating its properties with new values, similar to what Kotlindata class
offers.
Dependency Injection
- swift-blade: A macro powered dependency injection framework.
- MDI: High performance dependency injection framework.
- SwiftEnvironment: SwiftUI based Environment global dependency locator framework with macro.
- SafeDI: Compile-time safe dependency injection via code generation.
Testing
- Testable: A macro that produces tests hooks on DEBUG builds to allow testing private methods and properties.
- Mockable: Provides automatic mock implementations for your protocols and an intuitive syntax that simplifies the process of mocking services and verifying invocations in your unit tests.
- 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.
- SwiftNet: SwiftNet allows to create complex network request with built-in SSL/Certificate pinning, safe access token storage, automatic callback mechanism and the ability to build those requests as Combine's Publishers as well as Async/Await tasks. Framework also provides methods to test your requests easily with or without response model checks.
- Snowdrop: Super lightweight, type-safe, protocol based framework that includes simple and fast out of the box mocking, SSL/Certificate pinning, interception mechanism and the path variable default value support to bypass Swift protocol's limitations.
Enums
- CasePaths:
@CasePathable
produces key paths for enum cases, allowing enums to be used in dynamic member lookup and other generic algorithms. - ExtractCaseValue: A Swift macro that extracts associated values from enum cases.
- EnumeratorMacro: Generate custom code for your enums using Mustache templates.
- EnumRawValues: Enables full-fledged raw values for enums, supporting any equatable raw value types, assigning raw values with constants, expressions and more.
- EnumOptionSet: Enables more concise and safer declaration of option sets through enumeration notation.
Misc
- Protocol: A macro that produces a protocol based on a class/struct public interface.
- MacroKit: A collection of macros including:
@PublicInit
: Generate public memberwise init@GenerateMock
: Create a mock object for testing from a protocol@KeyPathIterable
: LikeCaseIterable
but for available keypaths on a type@StaticMemberIterable
: LikeCaseIterable
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 wrappingobjc_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. - Localize:
#Localize
An inline (freestanding) macro that expands toLocalizedStringResource
and works within Swift packages. - 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.
- MemoizeMacro: A macro for effortless function memoization in Swift
- 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. - Swift Macros: Contains a collection of useful macros:
#symbol
: Verify if SFSymbol is valid#URL
: Validate and return URL Object#unwrap
: Unwrap value.@AssociatedValues
: Add variables to retrieve the associated values.@Singleton
: Generate singleton code for struct and class.- More to come...
- Migrator: Migrator is a versatile Swift package designed to streamline the execution of asynchronous tasks with dependency management on all Apple platforms. The package also includes a handy macro for semantic versioning (SemVer 2.0.0).
#SemanticVersion("1.2.3")
- Equatable: A macro for synthesizing
Equatable
conformance for classes and actors. - CloakedString: A macro designed to improve the security of open text strings in Swift applications
Take part in this exciting evolution in Swift. Your contributions are most welcome!