
Product
Rust Support in Socket Is Now Generally Available
Socket’s Rust and Cargo support is now generally available, providing dependency analysis and supply chain visibility for Rust projects.
@bacons/xcode
Advanced tools
@bacons/xcodeThis project is a
work in progress / proof of conceptseemingly spec compliantpbxprojparser. The API is subject to breaking changes.
yarn add @bacons/xcode
Website https://xcode-seven.vercel.app/
Here is a diagram of the grammar used for parsing:
The most popular solution for parsing pbxproj files is a very old package by Cordova called xcode.
But xcode has some major issues:
Data type (<xx xx xx>).Consider the following format comparison.
Input .pbxproj
307D28A1123043350040C0FA /* app-icon.png */ = {
isa = PBXFileReference;
lastKnownFileType = image.png;
path = "app-icon.png";
sourceTree = "<group>";
};
xcode output (old)
{
"307D28A1123043350040C0FA_comment": "app-icon.png",
"308D052E1370CCF300D202BF": {
"isa": "PBXFileReference",
"lastKnownFileType": "image.png",
"path": "\"app-icon.png\"",
"sourceTree": "\"<group>\""
}
}
That same object would look like this in @bacons/xcode:
@bacons/xcode output (NEW)
{
"308D052E1370CCF300D202BF": {
"isa": "PBXFileReference",
"lastKnownFileType": "image.png",
"path": "app-icon.png",
"sourceTree": "<group>"
}
}
Notice how you don't need to strip or reapply quotes, you also don't need to filter out comments because the default visitor ignores comments in favor of regenerating them dynamically like Xcode does.
There's an experimental mutable-graph layer which makes it much easier to work with pbxproj.
import {
PBXAggregateTarget,
PBXFrameworksBuildPhase,
PBXLegacyTarget,
PBXNativeTarget,
XcodeProject,
} from "@bacons/xcode";
const project = XcodeProject.open("/path/to/project.pbxproj");
// Get all targets:
project.rootObject.props.targets
Create a Swift file:
import {PBXBuildFile,PBXFileReference } from '@bacons/xcode';
import path from 'path';
// Get `project` from XcodeProject.
const file = PBXBuildFile.create(project, {
fileRef: PBXFileReference.create(project, {
path: "MyFile.swift",
sourceTree: "<group>",
}),
})
// The file and fileRef will now be injected in the pbxproj `objects` dict.
<xx xx xx>.The parsing is very simple (simplicity is the key).
pbxproj is an "old-style plist" (or ASCII Plist), this means it should be possible to represent it as any other static configuration file type like JSON or XML.
We support the following types: Object, Array, Data, String. Notably, we avoid dealing with Integer, Double, Boolean since they appear to not exist in the format.
Docs are in the works. For now, you can refer to the types and the estimated pbxproj spec.
The API will change in the future, for now we have two methods:
import {
/** Given a stringified `pbxproj`, return a JSON representation of the object. */
parse,
/** Given a JSON representation of a `pbxproj`, return a `.pbxproj` string that can be parsed by Xcode. */
build,
} from "@bacons/xcode/json";
import fs from "fs";
import path from "path";
const pbxproj = parse(fs.readFileSync("/path/to/project.pbxproj"));
const pbxprojString = build(pbxproj);
PBXVariantGroup is a localized PBXGroup.Files will have an attribute sourceTree which indicates how the file path should be resolved.
BUILT_PRODUCTS_DIR: Paths are relative to the built products directory.DEVELOPER_DIR: Paths are relative to the developer directory.SOURCE_ROOT: Paths are relative to the project.SDKROOT: Paths are relative to the SDK directory.<group>: Paths are relative to the group.<absolute>: Source is an absolute path.For example, a file object like:
{
"isa": "PBXFileReference",
"name": "AppDelegate.m",
"path": "multitarget/AppDelegate.m",
"sourceTree": "<group>"
}
Indicates that the path "multitarget/AppDelegate.m" is relative to sourceTree "". We need to check the containing PBXGroup's path (only defined when the group is linked to a directory in the file system). Groups can live inside of other groups so this process is recursive.
Certain values loosely map to each other. For instance the top-level objectVersion (which indicates the versioning used for the objects in the top-level objects dictionary), maps to the rootObject -> PBXProject's compatibilityVersion string. Here is an up-to-date mapping (May 2022):
PBXProject.compatibilityVersion | XcodeProject.objectVersion |
|---|---|
'Xcode 15.0' | 60 |
'Xcode 14.0' | 56 |
'Xcode 13.0' | 55 |
'Xcode 12.0' | 54 |
'Xcode 11.4' | 53 |
'Xcode 11.0' | 52 |
'Xcode 10.0' | 51 |
'Xcode 9.3' | 50 |
'Xcode 8.0' | 48 |
'Xcode 6.3' | 47 |
'Xcode 3.2' | 46 |
'Xcode 3.1' | 45 |
FAQs
pbxproj parser
The npm package @bacons/xcode receives a total of 55,000 weekly downloads. As such, @bacons/xcode popularity was classified as popular.
We found that @bacons/xcode demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket’s Rust and Cargo support is now generally available, providing dependency analysis and supply chain visibility for Rust projects.

Security News
Chrome 144 introduces the Temporal API, a modern approach to date and time handling designed to fix long-standing issues with JavaScript’s Date object.

Research
Five coordinated Chrome extensions enable session hijacking and block security controls across enterprise HR and ERP platforms.