5

Is there a way to change file's target membership in Xcode project via command line?

Here's what I'm trying to do via Xcode's UI:

target membership

derpoliuk
  • 1,756
  • 2
  • 27
  • 43

1 Answers1

5

I also had to do this for CI. After lots of digging, I do not believe this is common enough for anyone to have written a tool to help with doing.

The only conclusion I came to was to edit the project.pbxproj file directly, which is never a great thing to do. None of the tools which claim to do this were of any help until I found this stackoverflow answer on editing the project.pbxproj file. Essentially, you can convert the project.pbxproj file into a JSON format using plutil -convert json project.pbxproj and use a JSON manipulation tool to make those files as headers then point them to be headers of whichever target you would like.

When converting the project.pbxproj into JSON format, be aware that Xcode will no longer be able to show you the project navigator for that project. It will still build and run, however, so this is really only useful if you're planning to do this right before building (such as for CI).

(EDIT: As of July 2022, Xcode will now properly read a JSON version of its .pbxproj to allow you to view your files in the project navigator. I'm not sure which version introduced this, but it is at least now possible with later versions of Xcode.)

The format project.pbxproj as JSON has nearly all the important data under the "objects" key. The file you want to be a header already has an entry with the key being the UUID for the file and a path value you can use to relate the UUID to your file. Here's an example of that format:

   // UUID for your file
   "65TYSSDXHSLP4UUOAD9D40C322AAGHM9": {
      "path": "MyHeader.h", // Your file's name
      "isa": "PBXFileReference",
      "includeInIndex": "1",
      "lastKnownFileType": "sourcecode.c.h",
      "sourceTree": "<group>"
    }

There's another entry to declare this file as a header, which has its own UUID and a reference to the UUID of your file:

    // UUID for your file as a header
    "YU3BSD39O9PT5RESDFV741D1": {
      "isa": "PBXBuildFile",
      "fileRef": "65TYSSDXHSLP4UUOAD9D40C322AAGHM9", // UUID for your file MyHeader.h
      "settings": {
        "ATTRIBUTES": [
          "Public" // could also be Project or Private
        ]
      }
    }

Then finally, your target has a list of header files where you will want the UUID for the header reference to go.

    "A82GAE9A5HUIO063IOPQAAQIUFGSNXZ": {
      "isa": "PBXHeadersBuildPhase",
      "buildActionMask": "2147483647",
      "files": [
        "YU3BSD39O9PT5RESDFV741D1" // UUID for your file as a header
      ],
      "runOnlyForDeploymentPostprocessing": "0"
    }

Again, changing the project.pbxproj file directly is never a great idea, but until there's a better tool for making these changes without using Xcode, it's the best I could find. If anyone else is aware of something I'm not, please let me know.

CodingLamb
  • 61
  • 1
  • 5