Xcode integration of Swift Package Plugins in Xcode 14
Xcode Extensions to the PackagePlugin API

WWDC 2022 video "Meet Swift Package plugins" explains how to perform actions on Swift packages and Xcode projects with Swift package plugins.
Swift Package plugins can be divided into two types:
- Command plugin
- Build tool plugin
Both plugin types were introduced in Swift 5.6 and work in Xcode 13.3 when used on Swift packages. So what's new in Xcode 14 (Swift 5.7) ?
Command plugins can be triggered within Xcode
No adoption from plugin authors is required :)
You can trigger the command plugin from the contextual menu

You can also trigger the command plugin from the "File Menu"

Both options will start the following dialog that lets you choose on which target(s) the command plugin shall be executed

Command plugins can be executed on Xcode projects
Adoption from plugin authors is required or otherwise you will receive the following error when triggering a command plugin on an Xcode project: Malformed input JSON: Couldn't find the XcodeProjectPlugin entry point
New in Xcode 14 is a library module called XcodeProjectPlugin which extends SPM's PackagePlugin API.
With the XcodeProjectPlugin API, a Swift package plugin can get a simplified description of the Xcode project’s structure (XcodePluginContext). The XcodePluginContext input structure is similar to the regular PluginContext structure, except that it provides access to an Xcode project that uses Xcode naming and semantics for the project model (which is somewhat different from that of SwiftPM).
Structure of a command plugin with conditional support for Xcode projects when running in Xcode
import PackagePlugin
@main
struct MyPlugin: CommandPlugin {
/// This entry point is called when operating on a Swift package.
func performCommand(context: PluginContext, arguments: [String]) throws {
print("Command plugin execution for Swift package \(context.package.displayName)")
}
}
#if canImport(XcodeProjectPlugin)
import XcodeProjectPlugin
extension MyPlugin: XcodeCommandPlugin {
/// 👇 This entry point is called when operating on an Xcode project.
func performCommand(context: XcodePluginContext, arguments: [String]) throws {
print("Command plugin execution for Xcode project \(context.xcodeProject.displayName)")
}
}
#endif
Build plugins can be executed on Xcode projects
A build tool plugin is able to conform to the new XcodeBuildToolPlugin type. This type was introduced in XcodeProjectPlugin with Xcode 14 Beta 3.
Structure of a build tool plugin with conditional support for Xcode projects when running in Xcode
import PackagePlugin
@main
struct MyPlugin: BuildToolPlugin {
/// This entry point is called when operating on a Swift package.
func createBuildCommands(context: PluginContext, target: Target) throws -> [Command]
return []
}
}
#if canImport(XcodeProjectPlugin)
import XcodeProjectPlugin
extension MyPlugin: XcodeBuildToolPlugin {
/// 👇 This entry point is called when operating on an Xcode project.
func createBuildCommands(context: XcodePluginContext, target: XcodeTarget) throws -> [Command]
return []
}
}
#endif
The Xcode target editor lets an App target be configured to use a build tool plugin provided by any of the project’s package dependencies.




