A python module to manipulate XCode projects

Overview
GitHub Workflow Status (branch) Codacy branch coverage Codacy grade PyPI PyPI - Downloads PyPI - License

pbxproj

This module can read, modify, and write a .pbxproj file from an Xcode 4+ projects. The file is usually called project.pbxproj and can be found inside the .xcodeproj bundle. Because some task cannot be done by clicking on an UI or opening Xcode to do it for you, this python module lets you automate the modification process.

How to use it

The typical tasks with an Xcode project are adding files to the project and setting some standard compilation flags. It can be achieved with a simple snippet like this:

from pbxproj import XcodeProject
# open the project
project = XcodeProject.load('myapp.xcodeproj/project.pbxproj')

# add a file to it, force=false to not add it if it's already in the project
project.add_file('MyClass.swift', force=False)

# set a Other Linker Flags
project.add_other_ldflags('-ObjC')

# save the project, otherwise your changes won't be picked up by Xcode
project.save()

That's it. More details about available API's visit the wiki.

Installation

For installation instructions visit the wiki

CLI

For instructions and commands available visit the wiki

Documentation

For general documentation, visit the wiki. For technical documentation, the public functions are documented and contains details about what is expected.

Reporting bugs

Did you find a bug? Too bad, but we want to help you, we need you to:

  • Check you are running python3 and installed the package using the pip3 command.
  • Provide as many details about the error you are having.
  • If possible provide a sample project.pbxproj to reproduce the steps
  • If possible, try the sequence of steps on Xcode and provide the project.pbxproj generated by Xcode.

We cannot help you if your issue is a title: "it does not work". Or if there is no sequence of steps to reproduce the error. Those kind of issues will be ignored or closed automatically.

Contributing

Do you want to fix an issue yourself? Great! some house rules:

  • Provide a description of what problem you are solving, what case was not being taking into account
  • Provide unit tests for the case you have fixed. Pull request without unit test or PRs that decrease the coverage will not be approved until this changes.
  • Adhere to the coding style and conventions of the project, for instance, target_name is used to specify the target across all functions that use this parameter. Changes will be requested on PRs that don't follow this.
  • Write descriptive commit messages.

License

This project is licensed using MIT license.

Comments
  • remove_group does not seem to work

    remove_group does not seem to work

    project.remove_group_by_name("Hola") Does not remove the group "Hola".

    And the following code creates the group "Hola" and leaves it present in the project. Shouldn't it remove it too?

    group = project.get_or_create_group("Hola")
    project.remove_group(group)
    project.save()
    
    bug 
    opened by da-mian 20
  • How can I get the project target

    How can I get the project target

    How can I get the project target. because when I use this script to add files to Pods project, the code seems not work, But if I drag the folder to Pods project, it can works. This is my code

    8dfa3268-ab1d-4e64-ad0f-d7f0904b6d2c

    project = XcodeProject.Load(pbxproj_file_path)
    project.remove_group_by_name('UIKit', True)
    project.save()
    
    if production:
        main_group = project.get_groups_by_name('DKNightVersion')[0]
        uikit_group = project.get_or_create_group('UIKit', None, main_group)
    else:
        main_group = project.get_or_create_group('DKNightVersion')
        pod_group = project.get_or_create_group('Pod', None, main_group)
        class_group = project.get_or_create_group('Classes', None, pod_group)
        uikit_group = project.get_or_create_group('UIKit', None, class_group)
    
    groups = json.load(open(json_file_path))
    
    for group, files in groups.iteritems():
        new_group = project.get_or_create_group(group, None, uikit_group)
        for f in files:
            project.add_file(f, new_group)
    
    project.save()
    

    39d31f05-c374-42fc-80ce-60fe593197eb

    opened by draveness 16
  • Unity 5 Xcode project and Library Linking

    Unity 5 Xcode project and Library Linking

    I've noticed that for the Xcode (v6.2) projects generated by Unity 5 (v5.0.0f4) add_file_if_doesnt_exist() no longer appears to be adding some frameworks to the list of libraries linked with the binary under the Build Phases tab of the Xcode project. The references to the frameworks to be added exist under the PBXFileReference section of the project.pbxproj but they don't exist under the PBXBuildFile section. I've seen this when adding the AdSupport.framework:

    project_path = '<project_path>/Unity-iPhone.xcodeproj/project.pbxproj'
    framework_path = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/AdSupport.framework'
    framework_group = project.get_or_create_group('Frameworks')
    project = XcodeProject.Load(project_path)
    project.add_file_if_doesnt_exist(framework_path, tree='SDKROOT', parent=framework_group )
    

    The create_build_files argument defaults to True and the weak argument defaults to False.

    I think what's happening is that only the objects under the PBXFileReference section of the project.pbxproj are being checked for the existence of the framework in the project where it should instead be checking both the reference and build sections. I believe that add_file_if_doesnt_exist() should work like the following:

    if (framework exists in PBXFileReference) {
        if (create_build_files == true) {
            if (!framework exists in PBXBuildFile) {
                create build files entry in project.pbxproj for the framework
            }
        }
        return []  // not sure about this in the case that the build files entry is added
    }
    return result from calling add_file()       
    
    bug 
    opened by jp-at-work 16
  • Enhancement Request: cli show/list content of pbxproj file

    Enhancement Request: cli show/list content of pbxproj file

    Hi,

    I was looking for a way to print out the content of a pbxproj file in a human readable format and came across this project. It would be awesome if I could use this project to print out information about build targets like the src files required, flags, etc. I don't believe this is currently supported by the cli program or the library.

    Thanks!

    enhancement 
    opened by kwhat 12
  • 'PBXBuildFile' object has no attribute 'fileRef'

    'PBXBuildFile' object has no attribute 'fileRef'

    I have the problem, if the module is adding flags and the project.pbxproj has errors like

    9D1494321F73F8AB0078CFF8 /* (null) in Sources */ = {isa = PBXBuildFile; };

    i'm getting

    'PBXBuildFile' object has no attribute 'fileRef'

    Is it possible to ignore these entries, or to remove this entries automatically from the file?

    enhancement 
    opened by erdnussflips 9
  • Is it possible to add a file to multiple targets?

    Is it possible to add a file to multiple targets?

    I'm developing a script to generate boilerplate code to my project. I have two targets (ag: Debug and Production) and I need to add files to these ones only. Right now we have the option to specify one target or add to all. Is it possible change the target to accept an array?

    enhancement 
    opened by leoneparise 8
  • [FEAT] Support XML format of pbxproj

    [FEAT] Support XML format of pbxproj

    Hello there! The issue arises in the XCode projects generated via openFrameworks (https://github.com/openframeworks/openFrameworks) projectGenerator that generates projects in XML format that it creates by modifying this template: https://github.com/openframeworks/openFrameworks/blob/b674f7ec1f41d8f0fcfea86e3d3d3df3e9bdcf36/scripts/templates/osx/emptyExample.xcodeproj/project.pbxproj

    If you open a project in XCode and then save it with some minimal change, it'll open, but without it it'll crash, apparently expecting JSON (?). Would be glad if anyone has anything to tell on this! Thanks.

    enhancement 
    opened by yeswecan 7
  • [BUG] add_folder always resolves paths as absolute

    [BUG] add_folder always resolves paths as absolute

    Describe the bug add_folder method in class ProjectFiles add absolute path to PBXGroup.

    I used the new script to provide a method like the old "apply_mods" , I found the add_folder method in class ProjectFiles add wrong path to PBXGroup, which expect the relpath,but absolute path wrote.

    System information

    1. pbxproj version used: 2.11
    2. python version used: python 3.8
    3. Xcode version used: 11.2.1
    bug not-enough-info 
    opened by u8-xiaohei 7
  • AttributeError: 'NoneType' object has no attribute 'isa'

    AttributeError: 'NoneType' object has no attribute 'isa'

    I'm using mod-pbxproj to manipulate an Xcode project file generated by Unity. In the script it removes a file from the project then adds some others, but it's raising the exception when it tries to add the first of those additional files. If the deletion is skipped then it works fine. It's quite a complicated project file, but I've reduced it down to a smaller test case and worked out that the presence of a file assigned to the "Unity-iPhone Tests" target triggers this problem - if that's removed from the project file then the script works.

    I've attached a tarball containing two example project files (one exhibiting this behaviour and one that doesn't) and a test script demonstrating the issue:

    bug.tar.gz

    bug answered 
    opened by markshep 7
  • Variant groups

    Variant groups

    This is an amended version of the variant groups branch. I'm not sure if this is the best way to submit changes.

    While testing it, I noticed a few issues which are fixed in this pull request:

    • attempting to add a PBXVariantGroup as a child of a PBXGroup gives an exception as it isn't one of the expected types.
    • adding multiple localisation files adds duplicate PBXBuildFiles for the variant group, which causes builds to fail as Xcode tries to copy the same file repeatedly.

    With these two fixes, I can confirm that the variant groups work as expected for our use case (localising the app icon name by localising the Info.plist file).

    But...

    One thing I did find is that the system will automatically add the variants to any existing variant group that exists with the same name - even when that variant group is for a different target. For example, our project has a 'tests' target that contains a InfoPlist.strings variant group that's stored in a separate folder. With the system as it is, any InfoPlist.strings files we add to the project get added to this variant group - even though we want to add them for our main target. This code in question is this:

    for variant in self.objects.get_objects_in_section(u'PBXVariantGroup'):
        if variant.name == expected_name:
    

    I don't entirely understand how all of this works, but to me this seems like the incorrect - or at least, unexpected behaviour. I believe you should be able to have multiple variant groups for the same file. I've worked around this by removing the exiting variant group.

    I also noticed that adding a strings file that's outside the project causes an exception on this line in ProjectFiles.py - I have't fixed this:

    library_path = os.path.join(u'$(SRCROOT)', os.path.split(file_ref.path)[0])

    AttributeError: 'PBXVariantGroup' object has no attribute 'path'

    opened by eAi 7
  • [BUG] Error in openstep_parser: string index out of range

    [BUG] Error in openstep_parser: string index out of range

    Describe the bug I'm trying to use the default sample code on the homepage just to check how mod-pbxproj works, however I stumbled upon this error:

    Traceback (most recent call last): File "xcode_python_setup.py", line 3, in project = XcodeProject.load('../myapp/myapp.xcodeproj/project.pbxproj') File "/Library/Python/2.7/site-packages/pbxproj/XcodeProject.py", line 90, in load tree = osp.OpenStepDecoder.ParseFromFile(open(path, 'r')) File "build/bdist.macosx-10.15-x86_64/egg/openstep_parser/openstep_parser.py", line 42, in ParseFromFile File "build/bdist.macosx-10.15-x86_64/egg/openstep_parser/openstep_parser.py", line 46, in ParseFromString File "build/bdist.macosx-10.15-x86_64/egg/openstep_parser/openstep_parser.py", line 51, in _parse IndexError: string index out of range

    System information

    1. pbxproj version used: 3.2.0
    2. python version used: 3.6.12
    3. Xcode version used: 12.0 (12A7209)

    To Reproduce Steps to reproduce the behavior:

    1. Created a .py file with this code

    from pbxproj import XcodeProject project = XcodeProject.load('../myapp/myapp.xcodeproj/project.pbxproj') project.save()

    1. On the terminal, cd to a related folder and ran: "python xcode_python_setup.py"
    2. See error

    Expected behavior Just expected to see a clear python command without any errors.

    bug invalid 
    opened by VitorMMOliveira 6
  • [BUG] Update multible Flags

    [BUG] Update multible Flags

    Trying to update ALL IPHONEOS_DEPLOYMENT_TARGET from 9.0 to 12.0

    System information pbxproj version used: pbxproj 3.4.0 python version used: Python 3.10.6 Xcode version used: xCode Version 14.0.1 (14A400)

    To Reproduce Installed pbxproj

    pip3 install pbxproj

    created "update_pbxproj.py"

    from pbxproj import XcodeProject
    # open
    project = XcodeProject.load('ios/Runner.xcodeproj/project.pbxproj')
    
    # set variables
    project.set_flags('IPHONEOS_DEPLOYMENT_TARGET', '12.0')
    
    # save
    project.save()
    

    run script

    python3 update_pbxproj.py
    

    after open then ios/Runner.xcodeproj/project.pbxproj still have IPHONEOS_DEPLOYMENT_TARGET = 9.0;

    Expected behavior Every flags IPHONEOS_DEPLOYMENT_TARGET = 12.0;

    Screenshots

    bug not-enough-info 
    opened by mklarsen 2
  • update flag

    update flag

    is there a way to update existing flag ?

    I want to update CODE_SIGN_STYLE flag to manual and code sign feature is not adding manual at all places in project file.

    enhancement 
    opened by sikandernoori 0
  • Moving an existing group to another group

    Moving an existing group to another group

    Hello,

    Is it possible to use mod-pbxproj to move one group inside another group? For example:

    > Group A
      - aGroupAFile.mm
    > Group B
    

    to

    > Group B
      > Group A
        - aGroupAFile.mm
    

    Couldn't find any info online. I'd greatly appreciate any pointers.

    Thanks!

    question not-enough-info 
    opened by bibhas 2
  • [FEAT] How to add sub-project into current project, but sub-project has two kinds of target type

    [FEAT] How to add sub-project into current project, but sub-project has two kinds of target type

    Is your feature request related to a problem? Please describe. There is a framework xcode project B, which has two different kinds of platform targets, iOS and MacOS. After I added this framework project B into another app xcode project A as a dependency library. You will find out that, the list of the Build Phases -> Link Binary With Libraries, has both two targets which belong xcode proj B, one is for iOS, another is for MacOS. But the aim of this action is to add one compatible framework into current project as a dependency library, and this behavior should be ensure the dependency library must match the major app's target platform type, like iOS only, or MacOS only.

    I think the method below should be refactored.

    def add_project(self, path, parent=None, tree=TreeType.GROUP, target_name=None, force=True, file_options=FileOptions())
    
    enhancement 
    opened by imeteora 0
  • Missing support for easily adding swift packages to project

    Missing support for easily adding swift packages to project

    I have not found an api to perform all steps required to add a swift package to project. When a swift package is added to an xcode project, it is modified as follows:

    • a single entry is added to XCRemoteSwiftPackageReference section
    • a single entry is added to PBXProject section
    • an entry for each package product is added to XCSwiftPackageProductDependency section
    • an entry for each package product is added to PBXFrameworksBuildPhase section, for given target
    • an entry for each package product is added to PBXBuildFile section (the entry has productRef attribute in place of fileRef), for given target
    • an entry for each package product is added to PBXNativeTarget section, for given target

    As a side note, a file *.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved is also created, but I think this is out of scope.

    I have modified mod-pbxproj and added an add_package function that performs the steps stated above. It can be used as follows:

    from pbxproj import XcodeProject
        
    # open the project
    project = XcodeProject.load('DummyProject/DummyProject.xcodeproj/project.pbxproj')
    
    project.add_package('https://github.com/SnapKit/SnapKit.git', 'SnapKit', 'DummyProject (iOS)', {
        "kind": "upToNextMajorVersion",
        "minimumVersion": "5.0.1"
    })
    project.add_package('https://github.com/openid/AppAuth-iOS.git', ['AppAuth','AppAuthCore'], 'DummyProject (iOS)', {
        "kind": "upToNextMajorVersion",
        "minimumVersion": "1.4.0"
    })
    
    project.save()
    

    You can take a look the patch https://github.com/kronenthaler/mod-pbxproj/compare/master...garrik:develop

    This code just suits my needs but if you find it a viable solution, I would be happy to add tests, refactor, accept suggestion for improvement and contribute a pull request. Regards

    enhancement 
    opened by garrik 1
  • [FEAT] Add support for Creating/Deleting On Demand Resource Tags

    [FEAT] Add support for Creating/Deleting On Demand Resource Tags

    Is your feature request related to a problem? Please describe. On Demand Resource tags can only be manipulated through Xcode's project settings GUI. This is very annoying when you have processes that install new resources into your application, but then need to manually tag their resources

    Describe the solution you'd like

    • Asset Tags are defined in the KnownAssetTags object in the 
 /* Begin PBXProject section */ It seems it would be fairly easy to mutate this list.
    • Additionally, each file references it's created ODR tag at the end of it's resource declaration 6A73EA5125C074F800669235 /* 265 in Resources */ = {isa = PBXBuildFile; fileRef = 6A73EA2725C074F000669235 /* 265 */; settings = {ASSET_TAGS = (265, ); }; };

    Describe alternatives you've considered Doesn't seem to be any support for this in the ecosystem, seems people are mutating their pbx files directly via shell scripts. Would be nice to add to this very nice library :)

    enhancement answered 
    opened by ignkarman 3
Releases(3.2.3)
Owner
Ignacio Calderon
Ignacio Calderon
HeadHunter parser

HHparser Description Program for finding work at HeadHunter service Features Find job Parse vacancies Dependencies python pip geckodriver firefox Inst

memphisboy 1 Oct 30, 2021
Link-tree - Script that iterate over the links found in each page

link-tree Script that iterate over the links found in each page, recursively fin

Rodrigo Stramantinoli 2 Jan 05, 2022
VerSign: Easy Signature Verification in Python

VerSign: Easy Signature Verification in Python versign is a small Python package which can be used to perform verification of offline signatures. It a

Muhammad Saif Ullah Khan 3 Dec 01, 2022
Aggregating gridded data (xarray) to polygons

A package to aggregate gridded data in xarray to polygons in geopandas using area-weighting from the relative area overlaps between pixels and polygons.

Kevin Schwarzwald 42 Nov 09, 2022
API Rate Limit Decorator

ratelimit APIs are a very common way to interact with web services. As the need to consume data grows, so does the number of API calls necessary to re

Tomas Basham 575 Jan 05, 2023
Keval allows you to call arbitrary Windows kernel-mode functions from user mode, even (and primarily) on another machine.

Keval Keval allows you to call arbitrary Windows kernel-mode functions from user mode, even (and primarily) on another machine. The user mode portion

42 Dec 17, 2022
A time table app to notify the user about their class timings

kivyTimeTable A time table app to notify the user about their class timings Features This project incorporates some features i wanted to see in a time

2 Dec 15, 2021
An OData v4 query parser and transpiler for Python

odata-query is a library that parses OData v4 filter strings, and can convert them to other forms such as Django Queries, SQLAlchemy Queries, or just plain SQL.

Gorilla 39 Jan 05, 2023
Script to decrypt / import chromium (edge/chrome) cookies

Cloonie Script to decrypt / import chromium (edge/chrome) cookies. Requirements Install the python dependencies via pip: pip install -r requirements.t

Lorenzo Bernardi 5 Sep 13, 2022
A sys-botbase client for remote control automation of Nintendo Switch consoles. Based on SysBot.NET, written in python.

SysBot.py A sys-botbase client for remote control automation of Nintendo Switch consoles. Based on SysBot.NET, written in python. Setup: Download the

7 Dec 16, 2022
This program organizes automatically files in folders named as file's extension

Auto Sorting System by Sergiy Grimoldi - V.0.0.2 This program organizes automatically files in folders named as file's extension How to use the code T

Sergiy Grimoldi 1 Jan 07, 2022
Software to help automate collecting crowdsourced annotations using Mechanical Turk.

Video Crowdsourcing Software to help automate collecting crowdsourced annotations using Mechanical Turk. The goal of this project is to enable crowdso

Mike Peven 1 Oct 25, 2021
PyResToolbox - A collection of Reservoir Engineering Utilities

pyrestoolbox A collection of Reservoir Engineering Utilities This set of functio

Mark W. Burgoyne 39 Oct 17, 2022
✨ Voici un code en Python par moi, et en français qui permet de générer du texte Lorem.

Lorem Gen ❗ Voici un code en Python par moi, et en français qui permet de générer du texte Lorem. Dépendences : pip install lorem_text 💖 Enjoy 🎫 Mon

MrGabin 3 Jun 07, 2021
Produce a simulate-able SDF of an arbitrary mesh with convex decomposition.

Mesh-to-SDF converter Given a (potentially nasty, nonconvex) mesh, automatically creates an SDF file that describes that object. The visual geometry i

Greg Izatt 22 Nov 23, 2022
A monitor than send discord webhook when a specific monitored product has stock in your nearby pickup stores.

Welcome to Apple In-store Monitor This is a monitor that are not fully scaled, and might still have some bugs.

5 Jun 16, 2022
general-phylomoji: a phylogenetic tree of emoji

general-phylomoji: a phylogenetic tree of emoji

2 Dec 11, 2021
A small python tool to get relevant values from SRI invoices

SriInvoiceProcessing A small python tool to get relevant values from SRI invoices Some useful info to run the tool Login into your SRI account and ret

Wladymir Brborich 2 Jan 07, 2022
python script to generate color coded resistor images

Resistor image generator I got nerdsniped into making this. It's not finished at all, and the code is messy. The end goal it generate a whole E-series

MichD 1 Nov 12, 2021
A Tool that provides automatic kerning for ligature based OpenType fonts in Microsoft Volt

Kerning A Tool that provides automatic kerning for ligature based OpenType fonts in Microsoft Volt There are three stages of the algorithm. The first

Sayed Zeeshan Asghar 6 Aug 01, 2022