XcodeProj Documentation

repository·main·Indexed 24 days ago

https://github.com/tuist/xcodeproj

A Swift library for parsing and manipulating Xcode project files. XcodeProj allows developers to programmatically read, modify, and write .xcodeproj files, facilitating the creation of automation tools and project generators. It provides APIs to iterate through project targets, manage build configurations, and create root groups within the pbxproj structure.

Tokens
1.6K
Snippets
7
Records
9
Agent score
81%

What's inside XcodeProj

  1. Migrate to xcodeproj 6

    main

    In xcodeproj 6, object unique identifiers are managed internally. You no longer need to pass identifiers manually to set dependencies between objects. This version introduces several breaking changes to the API:

    • PBXObjectReference is now internal: Instead of using reference objects, use attributes typed to the target object. For example, to add a configuration to an XCConfigurationList, use list.buildConfigurations.append(config).
    • Optionality of attributes: Object references are now attributes with specific optionality based on Xcode requirements:
      • Implicitly unwrapped optional: Used when the attribute is required by Xcode.
      • Explicitly unwrapped optional: Used when the attribute is optional by Xcode.
    • PBXObjects is now internal: Previously accessed via PBXProj.objects, methods for adding, removing, or getting objects have moved directly to the PBXProj class via public helpers.
  2. Migrate to xcodeproj 5

    main

    Migrating to xcodeproj 5 involves several breaking changes and API renames:

    • Rename Import: Change all import statements from import xcproj to import xcodeproj.
    • Dependency Management: Support for Carthage and CocoaPods has been removed. Use Swift Package Manager to manage the dependency manually.
    • Path Types: The Path type has been replaced by AbsolutePath and RelativePath from the Swift Package Manager's Basic framework. Update your code to use these new types.
    • Reference Attributes: Reference attributes now follow the naming convention attributeReference. To materialize a reference and retrieve the actual object, use the provided getters on objects (note that these getters throw if the object is not found).
  3. Install xcodeproj using swift-sh

    main

    If you want to run standalone Swift scripts without manually managing dependencies, you can use swift-sh. Add the following shebang and imports to the top of your Swift file. The dependency will be fetched automatically when you run the script from your terminal.

    #!/usr/bin/swift sh
    import Foundation
    import XcodeProj  // @tuist
    import PathKit
  4. Automate Xcode project tasks with scripting

    main

    You can use XcodeProj within Swift scripts to automate project maintenance, such as syncing version numbers. Using swift-sh, you can import XcodeProj and manipulate the pbxproj structure directly.

    In the example below, the script iterates through buildConfigurations to update a specific build setting (e.g., CURRENT_PROJECT_VERSION) and then calls write(path:) to save the changes to the .xcodeproj file.

    #!/usr/bin/swift sh
    import Foundation
    import XcodeProj  // @tuist ~> 8.8.0
    import PathKit
    
    guard CommandLine.arguments.count == 3 else {
        let arg0 = Path(CommandLine.arguments[0]).lastComponent
        fputs("usage: \(arg0) <project> <new-version>\n", stderr)
        exit(1)
    }
    
    let projectPath = Path(CommandLine.arguments[1])
    let newVersion = CommandLine.arguments[2]
    let xcodeproj = try XcodeProj(path: projectPath)
    let key = "CURRENT_PROJECT_VERSION"
    
    for conf in xcodeproj.pbxproj.buildConfigurations where conf.buildSettings[key] != nil {
        conf.buildSettings[key] = newVersion
    }
    
    try xcodeproj.write(path: projectPath)
  5. Iterate through project targets

    main

    Access the pbxproj attribute of an XcodeProj instance to interact with the underlying project structure. You can iterate over nativeTargets to access target information like names.

    let pbxproj = xcodeproj.pbxproj // Returns a PBXProj
    pbxproj.nativeTargets.forEach { target in
      print(target.name)
    }
  6. Create a new root group in an Xcode project

    main

    To add a group to the root of a project, access the project definition from the pbxproj attribute, retrieve the mainGroup, and use addGroup(named:).

    Note: Xcode expects the corresponding folder to exist in the file system relative to the project root. If the directory does not exist, Xcode will show a missing reference in the project navigator.

    let project = pbxproj.projects.first! // Returns a PBXProject
    let mainGroup = project.mainGroup
    mainGroup.addGroup(named: "MyGroup")
  7. Read an existing Xcode project

    main

    Use the XcodeProj class to parse and map an existing .xcodeproj file into Swift objects. The constructor requires the path to the project file.

    import Foundation
    import PathKit
    import XcodeProj
    
    let path = Path("/path/to/my/Project.xcodeproj") // Your project path
    do {
        let xcodeproj = try XcodeProj(path: path)
    } catch {
        print(error)
    }