24

Does anyone know of a library to read/write the Xcode project files .xcodeproj/.pbxproj? Any language is welcome.

Thanks in advance.

JP Richardson
  • 38,609
  • 36
  • 119
  • 151

8 Answers8

31

The surface syntax of an Xcode project is an "old-style plist." You can easily convert it to an XML plist with the command

plutil -convert xml1 -o - myproj.xcodeproj/project.pbxproj

Note this is not "real XML" but the Mac OS X plist structure expressed in XML syntax; it consists almost entirely of key-value pair dictionaries and arrays. Xcode will read the XML representation but convert it back to "old-style plist" when the project is opened.

The structure and relationship of the items in the plist follow the structure of the project. The UUIDs are used to cross-reference items between the project and its targets, and between the project and the user files in the project wrapper.

The 'isa' key identifies each kind of object. The PBXProject contains PBXFileReference, PBXGroup, PBXNativeTarget, and PBXBuildConfiguration objects.

The targets have PBXBuildPhase objects that contain cross-references to the file references; BuildConfigurationLists that store the build settings for the targets, and other target settings like the target type and name.

The buildConfigurationLists cross-reference buildConfigurations, which in turn contain dictionaries of buildSettings.

I'd recommend looking at the old-style plist text first, as it's much more readable and actually has inline comments to tell you what's what. Then you can use XML tools to edit or write the project files to your liking.

cdespinosa
  • 20,661
  • 6
  • 33
  • 39
  • Thanks for this response. This is a nice to lead to get me started. I'll be sure to let you know how it goes. – JP Richardson Sep 21 '09 at 19:29
  • 4
    is this reversible ? xml back to pbxproj ? – thndrkiss Jul 01 '13 at 09:48
  • @thndrkiss Xcode will happily read any of the list formats (xml, Jason, etc) and will revert back to native on save. If using ObjC / Swift perhaps no need to convert to XML as you can read the file directly into an NSDictionary. – Jasper Blues Jul 19 '14 at 00:53
  • 1
    @JasperBlues Xcode could not recognize the JSON format after I write back JSON to `project.pbxproj` by using Python `json.dump(json_dict, pbxproj_file)`. I got error note `MyProject.xcodeproj cannot be opened because the project file cannot be parsed.` Do you know why? Thanks. – Xiao Jul 31 '14 at 12:07
  • @sean interesting. Not sure why. Since it can write in a deprecated format, perhaps it's because whatever it's using is not the standard Cocoa stuff. Fortunately it *does* accept XML making it easy to write plugins etc. – Jasper Blues Jul 31 '14 at 20:28
21

I ended up creating one, and it's hosted on github here:

https://github.com/jasperblues/XcodeEditor

Allows listing headers, files, adding source files, setting source file as a member of a target, adding images, creating groups, etc).

It works by manipulating the contents of the project.pbxproj file. Used in:

  • Less Painful: Automated functional testing for mobile applications. (Edit: now part of Xamarin's tools).
  • Level Helper: A RAD framework for developing 2D games on iOS & Android.
  • TextMate
  • Apportable
Jasper Blues
  • 28,258
  • 22
  • 102
  • 185
6

I just discovered this: https://github.com/alunny/node-xcode I haven't used it yet, but it looks promising for Node.js developers.

JP Richardson
  • 38,609
  • 36
  • 119
  • 151
3

Try this one: https://github.com/sap-production/XcodeProjectJavaAPI

It can read and write any Property List file and contains a semantic model to read and manipulate Xcode Project files. The semantic model is in an early stage but can be easily extended.

It is also used heavily in the Xcode Maven plugin of SAP, which will be released this month.

Alexander
  • 1,495
  • 2
  • 19
  • 24
3

CocoaPods now have a ruby library to manipulate pbxproj files:

https://github.com/CocoaPods/Xcodeproj

As well as being used by CocoaPods, this is also used by fastlane, synx, slather and no doubt many more.

JosephH
  • 37,173
  • 19
  • 130
  • 154
3

You could also consider using the PlistBuddy command :

https://marcosantadev.com/manage-plist-files-plistbuddy/

http://scriptingosx.com/2016/11/editing-property-lists/

Cybernetic
  • 12,628
  • 16
  • 93
  • 132
ıɾuǝʞ
  • 2,829
  • 26
  • 38
2

There's a nice Python package for doing this. The documentation isn't great, but the source code is pretty organized and you can find what you need.

https://github.com/kronenthaler/mod-pbxproj

Sandy Chapman
  • 11,133
  • 3
  • 58
  • 67
-1

For PHP (easily ported to whatever language you need), very basic write only:

function modifyPlistXCodeProject($file_path,$app_name,$bundle_identifier,$latest_version,$bundle_version)
{
    $data = file_get_contents($file_path);
    $changes = Array();
    $changes['PRODUCT_BUNDLE_IDENTIFIER'] = $bundle_identifier;
    foreach ($changes as $key => $value){
        $data = oldStylePlistReplace($data,$key,$value);
    }
    file_put_contents($file_path, $data);
}

function oldStylePlistReplace($data,$key,$value){
    $e = explode($key,$data);
    for ($i=1;$i<count($e);$i++){
        $row_i = $e[$i];
        $nextline_pos = stripos($row_i,"\n");
        $text_i = '= '.$value.';'.substr($row_i, $nextline_pos);
        $e[$i] = $text_i;
        //var_dump(substr($text_i,0,100));exit();
    }
    return implode($key,$e);
}
user1122069
  • 1,767
  • 1
  • 24
  • 52