0
# Project Parsing and Writing
1
2
Core functionality for loading and saving Xcode project files with support for both asynchronous and synchronous operations.
3
4
## Capabilities
5
6
### Project Parsing
7
8
Parse Xcode project files (.pbxproj) into a manipulable JavaScript object structure.
9
10
```javascript { .api }
11
/**
12
* Parse project file asynchronously using worker process
13
* Uses a forked child process to avoid blocking the main thread
14
* @param {function} callback - Callback function(err, project)
15
*/
16
parse(callback);
17
18
/**
19
* Parse project file synchronously
20
* Blocks execution until parsing is complete
21
* @returns {pbxProject} Self for chaining
22
*/
23
parseSync();
24
```
25
26
**Usage Examples:**
27
28
```javascript
29
const xcode = require('xcode');
30
const proj = xcode.project('path/to/project.pbxproj');
31
32
// Asynchronous parsing (recommended for large projects)
33
proj.parse(function(err) {
34
if (err) {
35
console.error('Parse error:', err);
36
return;
37
}
38
39
console.log('Project parsed successfully');
40
console.log('Product name:', proj.productName);
41
42
// Project is ready for manipulation
43
proj.addSourceFile('MyNewFile.m');
44
});
45
46
// Synchronous parsing (simpler but blocking)
47
try {
48
proj.parseSync();
49
console.log('Project loaded:', proj.productName);
50
} catch (err) {
51
console.error('Parse error:', err);
52
}
53
```
54
55
### Project Writing
56
57
Serialize project data back to the pbxproj file format for saving to disk.
58
59
```javascript { .api }
60
/**
61
* Write project data to string format
62
* Converts the internal project structure back to pbxproj format
63
* @param {object} options - Formatting options for output control
64
* @returns {string} Serialized project data ready for file writing
65
*/
66
writeSync(options);
67
```
68
69
**Usage Examples:**
70
71
```javascript
72
const fs = require('fs');
73
74
// Basic writing
75
const projectData = proj.writeSync();
76
fs.writeFileSync('project.pbxproj', projectData);
77
78
// Writing with formatting options
79
const projectData = proj.writeSync({
80
omitEmptyValues: true, // Remove empty arrays/objects
81
omitBuildFileSection: false, // Keep build file section
82
omitGroupChildren: false // Keep group children arrays
83
});
84
fs.writeFileSync('project.pbxproj', projectData);
85
```
86
87
### Writer Options
88
89
```javascript { .api }
90
/**
91
* Options for controlling project serialization
92
*/
93
interface WriterOptions {
94
/** Remove empty values from output to reduce file size */
95
omitEmptyValues?: boolean;
96
97
/** Exclude build file section from output */
98
omitBuildFileSection?: boolean;
99
100
/** Exclude group children arrays from output */
101
omitGroupChildren?: boolean;
102
}
103
```
104
105
### Error Handling
106
107
The parsing operations can throw or return several types of errors:
108
109
```javascript
110
// Common error scenarios
111
proj.parse(function(err) {
112
if (err) {
113
if (err.name === 'SyntaxError') {
114
console.error('Invalid pbxproj file format:', err.message);
115
} else if (err.code) {
116
console.error('System error:', err.code, err.message);
117
} else {
118
console.error('Unknown parsing error:', err);
119
}
120
}
121
});
122
123
// Synchronous error handling
124
try {
125
proj.parseSync();
126
} catch (err) {
127
if (err.name === 'SyntaxError') {
128
throw new Error('Invalid project file format');
129
}
130
throw err;
131
}
132
```
133
134
### Project Data Structure
135
136
After parsing, the project data is available in the `hash` property:
137
138
```javascript { .api }
139
/**
140
* Parsed project data structure
141
*/
142
interface ProjectHash {
143
/** Project metadata and configuration */
144
project: {
145
/** Root object UUID */
146
rootObject: string;
147
148
/** Project object sections */
149
objects: {
150
/** Project configuration */
151
PBXProject: object;
152
153
/** Build files */
154
PBXBuildFile: object;
155
156
/** File references */
157
PBXFileReference: object;
158
159
/** Groups */
160
PBXGroup: object;
161
162
/** Native targets */
163
PBXNativeTarget: object;
164
165
/** Build configurations */
166
XCBuildConfiguration: object;
167
168
/** Configuration lists */
169
XCConfigurationList: object;
170
171
/** Build phases */
172
PBXSourcesBuildPhase: object;
173
PBXResourcesBuildPhase: object;
174
PBXFrameworksBuildPhase: object;
175
PBXCopyFilesBuildPhase?: object;
176
PBXShellScriptBuildPhase?: object;
177
178
/** Target dependencies */
179
PBXTargetDependency?: object;
180
PBXContainerItemProxy?: object;
181
182
/** Variant groups for localization */
183
PBXVariantGroup?: object;
184
185
/** Core Data version groups */
186
XCVersionGroup?: object;
187
};
188
};
189
}
190
```
191
192
**Usage Examples:**
193
194
```javascript
195
// Access parsed data directly
196
proj.parse(function(err) {
197
if (err) throw err;
198
199
// Access project sections
200
const buildFiles = proj.hash.project.objects.PBXBuildFile;
201
const fileReferences = proj.hash.project.objects.PBXFileReference;
202
const groups = proj.hash.project.objects.PBXGroup;
203
204
// Count files in project
205
const buildFileCount = Object.keys(buildFiles).filter(key => !key.endsWith('_comment')).length;
206
console.log('Build files in project:', buildFileCount);
207
208
// Find specific groups
209
for (let key in groups) {
210
if (!key.endsWith('_comment')) {
211
const group = groups[key];
212
console.log('Group:', group.name, 'Children:', group.children?.length || 0);
213
}
214
}
215
});
216
```