Skip to content

Manifests ​

Manifest is a .swift file that describes your xcode workspace. This document provides overview of basic manifest features.

Project.swift ​

Basic unit of any workspace is a project.

To create workspace with a single project simply add a Project.swift file:

swift
import ProjectDescription

let project = Project(
    name: "AwesomeApp"
)

Project.swift file should always contain exactly one instance of Project.

To generate .xcodeproj run geko generate.

TIP

Workspace.swift file is not necessary when workspace contains only one project.

Target ​

To add new target to project use parameter targets to Project:

swift
import ProjectDescription

let app = Target( 
    name: "AwesomeApp", 
    destinations: .iOS, 
    product: .app, 
    sources: "Sources/**/*.swift"
) 

let project = Project(
    name: "AwesomeApp",
    targets: [app] 
)

Dependencies between targets in the same project ​

To add dependency on a target withing the same project use parameter dependencies with value .target(name:):

swift
import ProjectDescription

let library = Target( 
    name: "AwesomeLibrary"
) 

let app = Target(
    name: "AwesomeApp",
    destinations: .iOS,
    product: .app,
    sources: "Sources/**/*.swift",
    dependencies: [ 
        .target(name: "AwesomeLibrary") 
    ] 
)

let project = Project(
    name: "AwesomeApp",
    targets: [app, library] 
)

WARNING

Keep in mind that .target(name:) cannot specify dependency on an external module or a target from another project. To do so, see sections Dependency on an external module and Dependencies between targets in different modules respectively.

Dependencies.swift ​

File Dependencies.swift allows to add cocoapods dependencies to workspace. For more info see Dependencies page.

To add dependency on an external module use .external(name:):

swift
import ProjectDescription

// ...

let app = Target(
    name: "AwesomeApp",
    destinations: .iOS,
    product: .app,
    sources: "Sources/**/*.swift",
    dependencies: [
        .target(name: "AwesomeLibrary"),
        .external(name: "ExternalLibrary") 
    ]
)

// ...
swift
import ProjectDescription

let cocoapodsDependencies = CocoapodsDependencies(
    repos: ["https://cdn.cocoapods.org"],
    dependencies: [
        .cdn(name: "ExternalLibrary")
    ]
)

let dependencies = Dependencies(cocoapodsDependencies: cocoapodsDependencies)

Workspace.swift ​

As the project grows, it is convenient to split it into several manifests. File Workspace.swift is needed to add add multiple Project.swift files into a workspace.

Example of Workspace.swift:

swift
import ProjectDescription

let workspace = Workspace(
    name: "AwesomeApp",
    projects: [
        // paths are pointing to directories containing Project.swift file
        "Sources/Library",
        "Sources/App",
    ]
)

Config.swift ​

File Config.swift allows to configure workspace options, such as build cache, project generation features and development environment restrictions.

Example of Config.swift file:

swift
import ProjectDescription

let config = Config(
    compatibleXcodeVersions: .upToNextMajor(Version(26, 0, 0)),
    cloud: .cloud(
        bucket: "bucket-name",
        url: "https://s3.company.name"
    ),
    cache: .cache(
        profiles: [
            .profile(
                name: "Debug-iOS",
                configuration: "Debug",
                platforms: [.iOS: .options(arch: .arm64)]
            )
        ]
    ),
    preFetchScripts: [
        .script("bundle install")
    ]
)

Dependencies between targets ​

Dependency on a target can be specified using 3 different accessors:

  • .target(name: "TargetName") specifies dependency on a target within the same project
  • .project(name: "TargetName", path: "Sources/Module") specifies dependency on a target within another concrete project
  • .local(name: "TargetName") specified dependency on a target from any project
swift
import ProjectDescription

let library = Target(
    name: "Library",
    product: .staticFramework,
    sources: "Sources/Library/**/*.swift",
)

let app = Target(
    name: "AwesomeApp",
    destinations: .iOS,
    product: .app,
    sources: "Sources/App/**/*.swift",
    dependencies: [
        // dependency on a target within the same project
        .target(name: "Library"),
        // dependency on a target `Library2` from project Sources/Library2/Project.swift
        .project(name: "Library2", path: "Sources/Library2"),
        // dependency on a terget `Library3` from another project
        .local(name: "Library3")
    ]
)

let project = Project(
    name: "AwesomeApp",
    targets: [app, library]
)