What is SwiftFormat?
masterself, removing redundant parentheses, and correcting deviations from standard Swift idioms to enforce a consistent coding style across projects.repository·master·Indexed 21 days ago
https://github.com/ekazaev/route-composerA protocol-oriented library for iOS that provides Cocoa UI abstractions to handle view controller composition, navigation, and deep linking, serving as a universal replacement for the Coordinator pattern.
self, removing redundant parentheses, and correcting deviations from standard Swift idioms to enforce a consistent coding style across projects.Rules are functions that apply changes to code. Most are enabled by default.
Command Line Management:
--rules (shows enabled/disabled status).--rule-info [rule_name] (or --rule-info for all).--disable rule1,rule2 or multiple --disable flags.--enable rule1,rule2 or multiple --enable flags.--disable all and then manually --enable specific rules, or use --rules rule1,rule2 to only enable a specific set.Inline Comment Management:
Use swiftformat: directives within Swift files:
// swiftformat:disable <rule1> <rule2>// swiftformat:enable <rule1> <rule2>// swiftformat:disable all / // swiftformat:enable all// swiftformat:disable:next <rule1> (disables rule for the next line only; no manual re-enable required).// swiftformat:disable:this <rule1> (disables for current line).// swiftformat:disable:previous <rule1> (disables for previous line).--disable redundantSelf,trailingClosures
--enable isEmpty
// swiftformat:disable <rule1> [<rule2> [rule<3> ...]]Some rules require specific Swift versions. If not specified, they may be disabled.
Swift Compiler Version:
--swift-version command-line argument.--swift-version to your .swiftformat file..swift-version file to your project directory (this takes precedence over the --swift-version argument).Swift Language Mode:
This is distinct from the compiler version (e.g., using Swift 6.0 compiler with Swift 5 language mode). Use --language-mode in CLI or .swiftformat files. If not specified, it defaults to the default mode of the specified compiler version (usually Swift 5.x).
--swift-version 5.9
--language-mode 6RouteComposer is built around three main entities that the host application must define to support navigation:
Factory: Responsible for building view controllers.Finder: Responsible for finding the appropriate destination or state.Action: Responsible for executing the navigation transition.Each of these entities uses two associatedtype parameters:
ViewController: The type of view controller being managed (e.g., UINavigationController, CustomViewController).Context: A payload object passed from the router to the view controllers. It is not a View Model or Presenter; it is the minimal information required to identify or configure the view (e.g., a UUID for a productID). It answers: "What do I need to present this view?" and "Am I already presenting this view for this specific context?"Options control the behavior of rules. You can configure them via command-line arguments, a .swiftformat configuration file, or inline comments.
Command Line:
Use --[option_name] [value]. To see all available options, use --options.
Configuration File:
Create a .swiftformat file in your project directory. Each line should contain one option.
Inline Comments:
Use // swiftformat:options to set options for a specific file or range. You can use modifiers to target specific lines:
:this: The current line.:next: The next line.:previous: The previous line.// Apply to the whole file
// swiftformat:options --indent 2 --allman true
// Apply only to this line
let indexUrl: URL // swiftformat:options:this --preserve-acronyms url
// Apply to the next line
// swiftformat:options:next --semicolons inline
doTheThing(); print("Did the thing")// swiftformat:options --indent 2 --allman true
let indexUrl: URL // swiftformat:options:this --preserve-acronyms url
// swiftformat:options:next --semicolons inline
doTheThing(); print("Did the thing")RouteComposer manages navigation within ContainerViewControllers (such as UINavigationController, UITabBarController, and UISplitViewController). Because each container has unique methods for interacting with its children, RouteComposer uses ContainerAdapters to abstract these interactions.
RouteComposer includes built-in adapters for standard UIKit container view controllers.ContainerAdapter to allow RouteComposer to switch tabs or manage visibility correctly.Refer to the ContainerAdapter protocol documentation for implementation details.
// Refer to the ContainerAdapter protocol for implementation details
// https://ekazaev.github.io/route-composer/Protocols/ContainerAdapter.htmlThe Router processes a chain of steps sequentially. For each step, it uses a Finder to check if the target UIViewController exists.
Router iterates through the chain until a Finder successfully locates the described UIViewController.Router moves backwards through the chain, using each step's Factory to create the required UIViewController and applying its associated Action to integrate it into the navigation stack.Mental Model: Think of configuration as defining a path for a user who could be anywhere in the app (e.g., arriving via a Universal Link) to reach a specific destination.
To ensure that upgrading SwiftFormat doesn't introduce new formatting rules that surprise you, use the --rules argument. By providing an exclusive list of rules in your SwiftFormat configuration, only those specified rules will be executed, and any new rules added in newer versions of SwiftFormat will be ignored.
# Example usage of specifying an exclusive list of rules
swiftformat --rules rule1,rule2,rule3 /path/to/codeIn addition to the core entities, RouteComposer provides three helping entities that you can implement to handle specific logic during the routing lifecycle:
RoutingInterceptor: Used to intercept and potentially modify the routing process.ContextTask: Used to handle tasks related to the Context during routing.PostRoutingTask: Used to execute actions after a routing operation has completed.The Xcode extension allows you to trigger formatting via the Editor > SwiftFormat menu within Xcode.
Via Homebrew (Recommended):
brew install --cask swiftformat-for-xcodeTo update: brew upgrade --cask swiftformat-for-xcode.
Manual Installation:
SwiftFormat for Xcode.app into your Applications folder.Note: Configuration is managed within the SwiftFormat for Xcode host application. You can import/export configurations via the File menu, but you must manually re-import .swiftformat files if they change, as the extension does not auto-detect changes to external config files.
If you are using Swift 5.6 or higher, you can use SwiftFormat as a command plugin. The plugin automatically detects and honors an existing .swiftformat configuration file in your package root.
Add SwiftFormat to your Package.swift dependencies:
Use the --allow-writing-to-package-directory flag to permit the plugin to modify files. You can use --target to limit formatting to a specific target and pass additional arguments like --swift-version.
In Xcode 14+, you can trigger the command plugin directly from the Xcode interface for a Swift package or an Xcode project.
// Package.swift
dependencies: [
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.58.7"),
]# CLI Usage
swift package plugin --allow-writing-to-package-directory swiftformat --target MyLibrary --swift-version 5.6 --verboseTo ensure code is formatted before every commit, you can use a Git pre-commit hook combined with git-format-staged.
git-format-staged..git/hooks/pre-commit in your project root.chmod +x .git/hooks/pre-commit.#!/bin/bash
git-format-staged --formatter "swiftformat stdin --stdin-path '{}'" "*.swift"