pbxplorer 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +186 -0
- data/Rakefile +8 -0
- data/lib/pbxplorer.rb +266 -0
- data/pbxplorer.gemspec +11 -0
- data/test/project.pbxproj +445 -0
- data/test/test_pbxplorer.rb +132 -0
- metadata +67 -0
data/README.md
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
# pbxplorer
|
2
|
+
|
3
|
+
pbxplorer is a set of Ruby classes for parsing, editing, and saving Xcode project (.pbxproj) files. It can also be used to explore the contents of a project using the interactive Ruby shell.
|
4
|
+
|
5
|
+
### Dependencies
|
6
|
+
|
7
|
+
pbxplorer has no Ruby dependencies outside of the standard library. It uses the OS X **plutil** command to parse the project file.
|
8
|
+
|
9
|
+
### Overview
|
10
|
+
|
11
|
+
An Xcode project (.pbxproj) file is essentially a hash of objects keyed by UUID. The objects are hashes of properties keyed by name. The associated values can be strings, arrays, or hashes.
|
12
|
+
|
13
|
+
Each object hash contains an "isa" property that identifies its type. pbxplorer loads a project file hash and replaces each generic object hash with a specific subclass based on its type.
|
14
|
+
|
15
|
+
### Class Hierarchy
|
16
|
+
|
17
|
+
PBXObject and PBXBuildPhase are abstract superclasses. All other subclasses of PBXObject correspond to object hashes in the project, based on their "isa" property.
|
18
|
+
|
19
|
+
```
|
20
|
+
PBXObject
|
21
|
+
PBXBuildFile
|
22
|
+
PBXBuildPhase
|
23
|
+
PBXFrameworksBuildPhase
|
24
|
+
PBXResourcesBuildPhase
|
25
|
+
PBXShellScriptBuildPhase
|
26
|
+
PBXSourcesBuildPhase
|
27
|
+
PBXFileReference
|
28
|
+
PBXGroup
|
29
|
+
PBXProject
|
30
|
+
PBXNativeTarget
|
31
|
+
XCBuildConfiguration
|
32
|
+
XCConfigurationList
|
33
|
+
XCProjectFile
|
34
|
+
```
|
35
|
+
|
36
|
+
### Reference Hierarchy
|
37
|
+
|
38
|
+
In the project file, objects are referenced from other objects by UUID. pbxplorer includes convenience methods to return the objects themselves rather than the UUIDs. Below are the method names and object types returned.
|
39
|
+
|
40
|
+
```
|
41
|
+
PBXProject
|
42
|
+
build_configuration_list: XCConfigurationList
|
43
|
+
main_group: PBXGroup
|
44
|
+
targets: [PBXNativeTarget]
|
45
|
+
|
46
|
+
XCConfigurationList
|
47
|
+
build_configurations: [XCBuildConfiguration]
|
48
|
+
|
49
|
+
PBXGroup
|
50
|
+
children: [PBXGroup|PBXFileReference]
|
51
|
+
subgroups: [PBXGroup]
|
52
|
+
file_refs: [PBXFileReference]
|
53
|
+
|
54
|
+
PBXNativeTarget
|
55
|
+
build_configuration_list: XCBuildConfigurationList
|
56
|
+
build_phases: [PBXBuildPhase]
|
57
|
+
product_file_ref: PBXFileReference
|
58
|
+
|
59
|
+
PBXBuildPhase
|
60
|
+
build_files: [PBXBuildFile]
|
61
|
+
|
62
|
+
PBXBuildFile
|
63
|
+
file_ref: PBXFileReference
|
64
|
+
```
|
65
|
+
|
66
|
+
### Interactive Use
|
67
|
+
|
68
|
+
To get started:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
$ irb
|
72
|
+
>> require 'pbxplorer'
|
73
|
+
=> true
|
74
|
+
>> XCProjectFile.help
|
75
|
+
project_file = XCProjectFile.new '/path/to/project.pbxproj'
|
76
|
+
=> XCProjectFile
|
77
|
+
```
|
78
|
+
|
79
|
+
The help displays a suggested statement followed by the type of the assigned result. Enter the statement in the shell, editing as necessary:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
>> project_file = XCProjectFile.new 'project.pbxproj'
|
83
|
+
=> {
|
84
|
+
rootObject = "4D0B81831657473000DEF560"
|
85
|
+
objects = < 63 objects >
|
86
|
+
}
|
87
|
+
```
|
88
|
+
|
89
|
+
This`XCProjectFile`instance contains a reference to the root object (a`PBXProject`instance), and the collection of all objects.
|
90
|
+
|
91
|
+
Get help from the **project_file** object:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
>> project_file.help
|
95
|
+
project = project_file.project
|
96
|
+
=> PBXProject
|
97
|
+
```
|
98
|
+
|
99
|
+
Enter the statement:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
>> project = project_file.project
|
103
|
+
=> 4D0B81831657473000DEF560 = {
|
104
|
+
attributes = {"CLASSPREFIX"=>"Example", "LastUpgradeCheck"=>"0450", "ORGANIZATIONNAME"=>"Example"}
|
105
|
+
projectRoot = ""
|
106
|
+
hasScannedForEncodings = "0"
|
107
|
+
mainGroup = "4D0B81811657473000DEF560"
|
108
|
+
buildConfigurationList = "4D0B81861657473000DEF560"
|
109
|
+
compatibilityVersion = "Xcode 3.2"
|
110
|
+
productRefGroup = "4D0B818D1657473000DEF560"
|
111
|
+
projectDirPath = ""
|
112
|
+
knownRegions = ["en"]
|
113
|
+
targets = ["4D0B818B1657473000DEF560", "4D0B81AC1657473100DEF560"]
|
114
|
+
developmentRegion = "English"
|
115
|
+
isa = "PBXProject"
|
116
|
+
}
|
117
|
+
```
|
118
|
+
|
119
|
+
This`PBXProject`instance contains an array of references to targets (`PBXNativeTarget`instances).
|
120
|
+
|
121
|
+
Get help from the **project** object:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
>> project.help
|
125
|
+
target = project.targets.first
|
126
|
+
=> PBXNativeTarget
|
127
|
+
list = project.build_configuration_list
|
128
|
+
=> XCConfigurationList
|
129
|
+
group = project.main_group
|
130
|
+
=> PBXGroup
|
131
|
+
```
|
132
|
+
|
133
|
+
This time the help suggests three objects we can retrieve next; the first`PBXNativeTarget`instance, the sole`XCConfigurationList`instance, and the main`PBXGroup`instance.
|
134
|
+
|
135
|
+
Enter the target statement:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
>> target = project.targets.first
|
139
|
+
=> 4D0B818B1657473000DEF560 = {
|
140
|
+
productName = "Example"
|
141
|
+
productReference = "4D0B818C1657473000DEF560"
|
142
|
+
name = "Example"
|
143
|
+
dependencies = []
|
144
|
+
buildConfigurationList = "4D0B81BF1657473100DEF560"
|
145
|
+
productType = "com.apple.product-type.application"
|
146
|
+
buildPhases = ["4D0B81881657473000DEF560", "4D0B81891657473000DEF560", "4D0B818A1657473000DEF560"]
|
147
|
+
isa = "PBXNativeTarget"
|
148
|
+
buildRules = []
|
149
|
+
}
|
150
|
+
```
|
151
|
+
|
152
|
+
You can continue exploring the object graph in this manner, down to `PBXFileReference`objects, which contain no references to other objects.
|
153
|
+
|
154
|
+
### Example: removing a source file
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
file_ref = project_file.objects_of_class(PBXFileReference, { "path" => "ExampleTests.m" }).first
|
158
|
+
build_phases = project_file.objects_of_class PBXBuildPhase
|
159
|
+
build_files = project_file.objects_of_class PBXBuildFile, { "fileRef" => file_ref.uuid }
|
160
|
+
build_file_uuids = build_files.map { |obj| obj.uuid }
|
161
|
+
groups = project_file.objects_of_class PBXGroup
|
162
|
+
|
163
|
+
build_phases.each { |phase| phase["files"] -= build_file_uuids }
|
164
|
+
build_files.each { |obj| project_file.remove_object obj }
|
165
|
+
groups.each { |group| group["children"].delete file_ref }
|
166
|
+
project_file.remove_object file_ref
|
167
|
+
|
168
|
+
project_file.save
|
169
|
+
```
|
170
|
+
|
171
|
+
### Example: adding a source file
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
file_ref = project_file.new_object PBXFileReference, { "path" => "Example.c", "sourceTree" => "<group>", "lastKnownFileType" => "sourcecode.c.c" }
|
175
|
+
build_file = project_file.new_object PBXBuildFile, { "fileRef" => file_ref.uuid }
|
176
|
+
|
177
|
+
build_phases = project_file.objects_of_class PBXSourcesBuildPhase
|
178
|
+
build_phases.each { |phase| phase["files"] << build_file.uuid }
|
179
|
+
|
180
|
+
project_file.save
|
181
|
+
```
|
182
|
+
|
183
|
+
## LICENSE
|
184
|
+
|
185
|
+
MIT license.
|
186
|
+
|
data/Rakefile
ADDED
data/lib/pbxplorer.rb
ADDED
@@ -0,0 +1,266 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class String
|
4
|
+
alias to_plist to_json
|
5
|
+
end
|
6
|
+
|
7
|
+
class Array
|
8
|
+
def to_plist
|
9
|
+
items = self.map { |item| "#{item.to_plist}" }
|
10
|
+
"( #{items.join ","} )"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Hash
|
15
|
+
def to_plist
|
16
|
+
items = self.map { |key, val| "#{key.to_plist} = #{val.to_plist};\n" }
|
17
|
+
"{ #{items.join} }"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class PBXObject < Hash
|
22
|
+
attr_accessor :project_file
|
23
|
+
attr_reader :uuid
|
24
|
+
|
25
|
+
def self.filter objs, attrs
|
26
|
+
objs.select do |obj|
|
27
|
+
attrs.select { |key, val| obj[key] == val }.length == attrs.length
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.objects_of_class objs, attrs=nil
|
32
|
+
objs = objs.select { |obj| obj.class <= self }
|
33
|
+
objs = self.filter(objs, attrs) if attrs
|
34
|
+
objs
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize hash={}, uuid=""
|
38
|
+
24.times { uuid += "0123456789ABCDEF"[rand(16),1] } if uuid.empty?
|
39
|
+
|
40
|
+
@project = nil
|
41
|
+
@uuid = uuid
|
42
|
+
|
43
|
+
self.merge! hash
|
44
|
+
self["isa"] ||= self.class.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def inspect
|
48
|
+
props = self.map { |key, val| " #{key} = #{val.inspect}\n" }
|
49
|
+
"#{@uuid} = {\n#{props.join}}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def help
|
53
|
+
puts "(no help available)"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class PBXFileReference < PBXObject
|
58
|
+
end
|
59
|
+
|
60
|
+
class PBXBuildFile < PBXObject
|
61
|
+
def file_ref
|
62
|
+
self.project_file.object_with_uuid self["fileRef"]
|
63
|
+
end
|
64
|
+
|
65
|
+
def help
|
66
|
+
puts "file_ref = build_file.file_ref"
|
67
|
+
PBXFileReference
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class PBXBuildPhase < PBXObject
|
72
|
+
def build_files
|
73
|
+
self.project_file.objects_with_uuids self["files"]
|
74
|
+
end
|
75
|
+
|
76
|
+
def help
|
77
|
+
puts "build_file = build_phase.build_files.first"
|
78
|
+
PBXBuildFile
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class PBXSourcesBuildPhase < PBXBuildPhase
|
83
|
+
end
|
84
|
+
|
85
|
+
class PBXFrameworksBuildPhase < PBXBuildPhase
|
86
|
+
end
|
87
|
+
|
88
|
+
class PBXResourcesBuildPhase < PBXBuildPhase
|
89
|
+
end
|
90
|
+
|
91
|
+
class PBXShellScriptBuildPhase < PBXBuildPhase
|
92
|
+
end
|
93
|
+
|
94
|
+
class PBXGroup < PBXObject
|
95
|
+
def children recursive=false
|
96
|
+
children = self.project_file.objects_with_uuids self["children"]
|
97
|
+
|
98
|
+
if recursive
|
99
|
+
subgroups = PBXGroup.objects_of_class children
|
100
|
+
subgroups.each { |subgroup| children << subgroup.children(true) }
|
101
|
+
end
|
102
|
+
|
103
|
+
children.flatten
|
104
|
+
end
|
105
|
+
|
106
|
+
def file_refs recursive=false
|
107
|
+
PBXFileReference.objects_of_class self.children(recursive)
|
108
|
+
end
|
109
|
+
|
110
|
+
def subgroups recursive=false
|
111
|
+
PBXGroup.objects_of_class self.children(recursive)
|
112
|
+
end
|
113
|
+
|
114
|
+
def help
|
115
|
+
puts "file_ref = group.file_refs.first\n=> " + PBXFileReference.to_s
|
116
|
+
puts "group = group.subgroups.first"
|
117
|
+
PBXGroup
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class PBXNativeTarget < PBXObject
|
122
|
+
def build_phases
|
123
|
+
self.project_file.objects_with_uuids self["buildPhases"]
|
124
|
+
end
|
125
|
+
|
126
|
+
def build_configuration_list
|
127
|
+
self.project_file.object_with_uuid self["buildConfigurationList"]
|
128
|
+
end
|
129
|
+
|
130
|
+
def product_file_ref
|
131
|
+
self.project_file.object_with_uuid self["productReference"]
|
132
|
+
end
|
133
|
+
|
134
|
+
def help
|
135
|
+
puts "build_phase = PBXSourcesBuildPhase.objects_of_class(target.build_phases).first"
|
136
|
+
PBXSourcesBuildPhase
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class XCBuildConfiguration < PBXObject
|
141
|
+
end
|
142
|
+
|
143
|
+
class XCConfigurationList < PBXObject
|
144
|
+
def build_configurations
|
145
|
+
self.project_file.objects_with_uuids self["buildConfigurations"]
|
146
|
+
end
|
147
|
+
|
148
|
+
def help
|
149
|
+
puts "config = list.build_configurations.first"
|
150
|
+
XCBuildConfiguration
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class PBXProject < PBXObject
|
155
|
+
def targets
|
156
|
+
self.project_file.objects_with_uuids self["targets"]
|
157
|
+
end
|
158
|
+
|
159
|
+
def build_configuration_list
|
160
|
+
self.project_file.object_with_uuid self["buildConfigurationList"]
|
161
|
+
end
|
162
|
+
|
163
|
+
def main_group
|
164
|
+
self.project_file.object_with_uuid self["mainGroup"]
|
165
|
+
end
|
166
|
+
|
167
|
+
def help
|
168
|
+
puts "target = project.targets.first\n=> " + PBXNativeTarget.to_s
|
169
|
+
puts "list = project.build_configuration_list\n=> " + XCConfigurationList.to_s
|
170
|
+
puts "group = project.main_group"
|
171
|
+
PBXGroup
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
class XCProjectFile
|
176
|
+
def self.help
|
177
|
+
puts "project_file = XCProjectFile.new '/path/to/project.pbxproj'"
|
178
|
+
XCProjectFile
|
179
|
+
end
|
180
|
+
|
181
|
+
def initialize path
|
182
|
+
@path = path
|
183
|
+
@path += "/project.pbxproj" if File.directory? @path
|
184
|
+
|
185
|
+
@json = JSON.parse(`plutil -convert json -o - "#{@path}"`)
|
186
|
+
|
187
|
+
objs = @json["objects"]
|
188
|
+
@json["objects"] = {}
|
189
|
+
|
190
|
+
objs.each do |uuid, hash|
|
191
|
+
klass = PBXObject
|
192
|
+
begin
|
193
|
+
klass = Object.const_get hash["isa"]
|
194
|
+
rescue
|
195
|
+
end
|
196
|
+
|
197
|
+
self.add_object klass.new(hash, uuid)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def save path=nil
|
202
|
+
path ||= @path
|
203
|
+
File.open(path, "w") { |f| f.write @json.to_plist }
|
204
|
+
end
|
205
|
+
|
206
|
+
def project
|
207
|
+
self.object_with_uuid @json["rootObject"]
|
208
|
+
end
|
209
|
+
|
210
|
+
def uuids
|
211
|
+
@json["objects"].keys
|
212
|
+
end
|
213
|
+
|
214
|
+
def objects
|
215
|
+
@json["objects"].values
|
216
|
+
end
|
217
|
+
|
218
|
+
def objects_of_class klass, attrs=nil
|
219
|
+
klass.objects_of_class self.objects, attrs
|
220
|
+
end
|
221
|
+
|
222
|
+
def objects_with_uuids uuids, attrs=nil
|
223
|
+
objs = uuids.map { |uuid| self.object_with_uuid uuid }.reject { |obj| !obj }
|
224
|
+
objs = PBXObject.filter(objs, attrs) if attrs
|
225
|
+
objs
|
226
|
+
end
|
227
|
+
|
228
|
+
def object_with_uuid uuid
|
229
|
+
@json["objects"][uuid]
|
230
|
+
end
|
231
|
+
|
232
|
+
def new_object klass, attrs={}
|
233
|
+
obj = klass.new attrs
|
234
|
+
self.add_object obj
|
235
|
+
obj
|
236
|
+
end
|
237
|
+
|
238
|
+
def add_object obj
|
239
|
+
obj.project_file = self
|
240
|
+
@json["objects"][obj.uuid] = obj
|
241
|
+
end
|
242
|
+
|
243
|
+
def remove_object obj
|
244
|
+
obj.project_file = nil
|
245
|
+
@json["objects"].delete obj.uuid
|
246
|
+
end
|
247
|
+
|
248
|
+
def remove_file_ref file_ref
|
249
|
+
build_files = self.objects_of_class PBXBuildFile, { "fileRef" => file_ref.uuid }
|
250
|
+
build_file_uuids = build_files.map { |obj| obj.uuid }
|
251
|
+
|
252
|
+
build_files.each { |build_file| self.remove_object build_file }
|
253
|
+
self.objects_of_class(PBXBuildPhase).each { |phase| phase["files"] -= build_file_uuids }
|
254
|
+
self.objects_of_class(PBXGroup).each { |group| group["children"].delete file_ref }
|
255
|
+
self.remove_object file_ref
|
256
|
+
end
|
257
|
+
|
258
|
+
def help
|
259
|
+
puts "project = project_file.project"
|
260
|
+
PBXProject
|
261
|
+
end
|
262
|
+
|
263
|
+
def inspect
|
264
|
+
"{\n rootObject = #{@json['rootObject'].inspect}\n objects = < #{@json['objects'].length} objects >\n}"
|
265
|
+
end
|
266
|
+
end
|
data/pbxplorer.gemspec
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "pbxplorer"
|
3
|
+
s.version = "1.0.0"
|
4
|
+
s.date = "2013-03-19"
|
5
|
+
s.summary = "Xcode project file editor"
|
6
|
+
s.description = "pbxplorer is a set of Ruby classes for parsing, editing, and saving Xcode project (.pbxproj) files. It can also be used to explore the contents of a project using the interactive Ruby shell."
|
7
|
+
s.authors = ["Mark Smith"]
|
8
|
+
s.email = "mark@camazotz.com"
|
9
|
+
s.files = Dir["{test,lib}/**/*"] + ["README.md", "Rakefile", "pbxplorer.gemspec"]
|
10
|
+
s.homepage = "http://github.com/mjmsmith/pbxplorer"
|
11
|
+
end
|
@@ -0,0 +1,445 @@
|
|
1
|
+
// !$*UTF8*$!
|
2
|
+
{
|
3
|
+
archiveVersion = 1;
|
4
|
+
classes = {
|
5
|
+
};
|
6
|
+
objectVersion = 46;
|
7
|
+
objects = {
|
8
|
+
|
9
|
+
/* Begin PBXBuildFile section */
|
10
|
+
4D0B81911657473000DEF560 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D0B81901657473000DEF560 /* UIKit.framework */; };
|
11
|
+
4D0B81931657473000DEF560 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D0B81921657473000DEF560 /* Foundation.framework */; };
|
12
|
+
4D0B81951657473000DEF560 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D0B81941657473000DEF560 /* CoreGraphics.framework */; };
|
13
|
+
4D0B819B1657473000DEF560 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D0B81991657473000DEF560 /* InfoPlist.strings */; };
|
14
|
+
4D0B819D1657473000DEF560 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D0B819C1657473000DEF560 /* main.m */; };
|
15
|
+
4D0B81A11657473000DEF560 /* ExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D0B81A01657473000DEF560 /* ExampleAppDelegate.m */; };
|
16
|
+
4D0B81A31657473000DEF560 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D0B81A21657473000DEF560 /* Default.png */; };
|
17
|
+
4D0B81A51657473000DEF560 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D0B81A41657473000DEF560 /* Default@2x.png */; };
|
18
|
+
4D0B81A71657473000DEF560 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D0B81A61657473000DEF560 /* Default-568h@2x.png */; };
|
19
|
+
4D0B81AF1657473100DEF560 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D0B81AE1657473100DEF560 /* SenTestingKit.framework */; };
|
20
|
+
4D0B81B01657473100DEF560 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D0B81901657473000DEF560 /* UIKit.framework */; };
|
21
|
+
4D0B81B11657473100DEF560 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D0B81921657473000DEF560 /* Foundation.framework */; };
|
22
|
+
4D0B81B91657473100DEF560 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D0B81B71657473100DEF560 /* InfoPlist.strings */; };
|
23
|
+
4D0B81BC1657473100DEF560 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D0B81BB1657473100DEF560 /* ExampleTests.m */; };
|
24
|
+
/* End PBXBuildFile section */
|
25
|
+
|
26
|
+
/* Begin PBXContainerItemProxy section */
|
27
|
+
4D0B81B21657473100DEF560 /* PBXContainerItemProxy */ = {
|
28
|
+
isa = PBXContainerItemProxy;
|
29
|
+
containerPortal = 4D0B81831657473000DEF560 /* Project object */;
|
30
|
+
proxyType = 1;
|
31
|
+
remoteGlobalIDString = 4D0B818B1657473000DEF560;
|
32
|
+
remoteInfo = Example;
|
33
|
+
};
|
34
|
+
/* End PBXContainerItemProxy section */
|
35
|
+
|
36
|
+
/* Begin PBXFileReference section */
|
37
|
+
4D0B818C1657473000DEF560 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
38
|
+
4D0B81901657473000DEF560 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
39
|
+
4D0B81921657473000DEF560 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
40
|
+
4D0B81941657473000DEF560 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
41
|
+
4D0B81981657473000DEF560 /* Example-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Example-Info.plist"; sourceTree = "<group>"; };
|
42
|
+
4D0B819A1657473000DEF560 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
43
|
+
4D0B819C1657473000DEF560 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
44
|
+
4D0B819E1657473000DEF560 /* Example-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Example-Prefix.pch"; sourceTree = "<group>"; };
|
45
|
+
4D0B819F1657473000DEF560 /* ExampleAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExampleAppDelegate.h; sourceTree = "<group>"; };
|
46
|
+
4D0B81A01657473000DEF560 /* ExampleAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleAppDelegate.m; sourceTree = "<group>"; };
|
47
|
+
4D0B81A21657473000DEF560 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
|
48
|
+
4D0B81A41657473000DEF560 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; };
|
49
|
+
4D0B81A61657473000DEF560 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
|
50
|
+
4D0B81AD1657473100DEF560 /* ExampleTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
|
51
|
+
4D0B81AE1657473100DEF560 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
|
52
|
+
4D0B81B61657473100DEF560 /* ExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleTests-Info.plist"; sourceTree = "<group>"; };
|
53
|
+
4D0B81B81657473100DEF560 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
54
|
+
4D0B81BA1657473100DEF560 /* ExampleTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExampleTests.h; sourceTree = "<group>"; };
|
55
|
+
4D0B81BB1657473100DEF560 /* ExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleTests.m; sourceTree = "<group>"; };
|
56
|
+
/* End PBXFileReference section */
|
57
|
+
|
58
|
+
/* Begin PBXFrameworksBuildPhase section */
|
59
|
+
4D0B81891657473000DEF560 /* Frameworks */ = {
|
60
|
+
isa = PBXFrameworksBuildPhase;
|
61
|
+
buildActionMask = 2147483647;
|
62
|
+
files = (
|
63
|
+
4D0B81911657473000DEF560 /* UIKit.framework in Frameworks */,
|
64
|
+
4D0B81931657473000DEF560 /* Foundation.framework in Frameworks */,
|
65
|
+
4D0B81951657473000DEF560 /* CoreGraphics.framework in Frameworks */,
|
66
|
+
);
|
67
|
+
runOnlyForDeploymentPostprocessing = 0;
|
68
|
+
};
|
69
|
+
4D0B81A91657473100DEF560 /* Frameworks */ = {
|
70
|
+
isa = PBXFrameworksBuildPhase;
|
71
|
+
buildActionMask = 2147483647;
|
72
|
+
files = (
|
73
|
+
4D0B81AF1657473100DEF560 /* SenTestingKit.framework in Frameworks */,
|
74
|
+
4D0B81B01657473100DEF560 /* UIKit.framework in Frameworks */,
|
75
|
+
4D0B81B11657473100DEF560 /* Foundation.framework in Frameworks */,
|
76
|
+
);
|
77
|
+
runOnlyForDeploymentPostprocessing = 0;
|
78
|
+
};
|
79
|
+
/* End PBXFrameworksBuildPhase section */
|
80
|
+
|
81
|
+
/* Begin PBXGroup section */
|
82
|
+
4D0B81811657473000DEF560 = {
|
83
|
+
isa = PBXGroup;
|
84
|
+
children = (
|
85
|
+
4D0B81961657473000DEF560 /* Example */,
|
86
|
+
4D0B81B41657473100DEF560 /* ExampleTests */,
|
87
|
+
4D0B818F1657473000DEF560 /* Frameworks */,
|
88
|
+
4D0B818D1657473000DEF560 /* Products */,
|
89
|
+
);
|
90
|
+
sourceTree = "<group>";
|
91
|
+
};
|
92
|
+
4D0B818D1657473000DEF560 /* Products */ = {
|
93
|
+
isa = PBXGroup;
|
94
|
+
children = (
|
95
|
+
4D0B818C1657473000DEF560 /* Example.app */,
|
96
|
+
4D0B81AD1657473100DEF560 /* ExampleTests.octest */,
|
97
|
+
);
|
98
|
+
name = Products;
|
99
|
+
sourceTree = "<group>";
|
100
|
+
};
|
101
|
+
4D0B818F1657473000DEF560 /* Frameworks */ = {
|
102
|
+
isa = PBXGroup;
|
103
|
+
children = (
|
104
|
+
4D0B81901657473000DEF560 /* UIKit.framework */,
|
105
|
+
4D0B81921657473000DEF560 /* Foundation.framework */,
|
106
|
+
4D0B81941657473000DEF560 /* CoreGraphics.framework */,
|
107
|
+
4D0B81AE1657473100DEF560 /* SenTestingKit.framework */,
|
108
|
+
);
|
109
|
+
name = Frameworks;
|
110
|
+
sourceTree = "<group>";
|
111
|
+
};
|
112
|
+
4D0B81961657473000DEF560 /* Example */ = {
|
113
|
+
isa = PBXGroup;
|
114
|
+
children = (
|
115
|
+
4D0B819F1657473000DEF560 /* ExampleAppDelegate.h */,
|
116
|
+
4D0B81A01657473000DEF560 /* ExampleAppDelegate.m */,
|
117
|
+
4D0B81971657473000DEF560 /* Supporting Files */,
|
118
|
+
);
|
119
|
+
path = Example;
|
120
|
+
sourceTree = "<group>";
|
121
|
+
};
|
122
|
+
4D0B81971657473000DEF560 /* Supporting Files */ = {
|
123
|
+
isa = PBXGroup;
|
124
|
+
children = (
|
125
|
+
4D0B81981657473000DEF560 /* Example-Info.plist */,
|
126
|
+
4D0B81991657473000DEF560 /* InfoPlist.strings */,
|
127
|
+
4D0B819C1657473000DEF560 /* main.m */,
|
128
|
+
4D0B819E1657473000DEF560 /* Example-Prefix.pch */,
|
129
|
+
4D0B81A21657473000DEF560 /* Default.png */,
|
130
|
+
4D0B81A41657473000DEF560 /* Default@2x.png */,
|
131
|
+
4D0B81A61657473000DEF560 /* Default-568h@2x.png */,
|
132
|
+
);
|
133
|
+
name = "Supporting Files";
|
134
|
+
sourceTree = "<group>";
|
135
|
+
};
|
136
|
+
4D0B81B41657473100DEF560 /* ExampleTests */ = {
|
137
|
+
isa = PBXGroup;
|
138
|
+
children = (
|
139
|
+
4D0B81BA1657473100DEF560 /* ExampleTests.h */,
|
140
|
+
4D0B81BB1657473100DEF560 /* ExampleTests.m */,
|
141
|
+
4D0B81B51657473100DEF560 /* Supporting Files */,
|
142
|
+
);
|
143
|
+
path = ExampleTests;
|
144
|
+
sourceTree = "<group>";
|
145
|
+
};
|
146
|
+
4D0B81B51657473100DEF560 /* Supporting Files */ = {
|
147
|
+
isa = PBXGroup;
|
148
|
+
children = (
|
149
|
+
4D0B81B61657473100DEF560 /* ExampleTests-Info.plist */,
|
150
|
+
4D0B81B71657473100DEF560 /* InfoPlist.strings */,
|
151
|
+
);
|
152
|
+
name = "Supporting Files";
|
153
|
+
sourceTree = "<group>";
|
154
|
+
};
|
155
|
+
/* End PBXGroup section */
|
156
|
+
|
157
|
+
/* Begin PBXNativeTarget section */
|
158
|
+
4D0B818B1657473000DEF560 /* Example */ = {
|
159
|
+
isa = PBXNativeTarget;
|
160
|
+
buildConfigurationList = 4D0B81BF1657473100DEF560 /* Build configuration list for PBXNativeTarget "Example" */;
|
161
|
+
buildPhases = (
|
162
|
+
4D0B81881657473000DEF560 /* Sources */,
|
163
|
+
4D0B81891657473000DEF560 /* Frameworks */,
|
164
|
+
4D0B818A1657473000DEF560 /* Resources */,
|
165
|
+
);
|
166
|
+
buildRules = (
|
167
|
+
);
|
168
|
+
dependencies = (
|
169
|
+
);
|
170
|
+
name = Example;
|
171
|
+
productName = Example;
|
172
|
+
productReference = 4D0B818C1657473000DEF560 /* Example.app */;
|
173
|
+
productType = "com.apple.product-type.application";
|
174
|
+
};
|
175
|
+
4D0B81AC1657473100DEF560 /* ExampleTests */ = {
|
176
|
+
isa = PBXNativeTarget;
|
177
|
+
buildConfigurationList = 4D0B81C21657473100DEF560 /* Build configuration list for PBXNativeTarget "ExampleTests" */;
|
178
|
+
buildPhases = (
|
179
|
+
4D0B81A81657473100DEF560 /* Sources */,
|
180
|
+
4D0B81A91657473100DEF560 /* Frameworks */,
|
181
|
+
4D0B81AA1657473100DEF560 /* Resources */,
|
182
|
+
4D0B81AB1657473100DEF560 /* ShellScript */,
|
183
|
+
);
|
184
|
+
buildRules = (
|
185
|
+
);
|
186
|
+
dependencies = (
|
187
|
+
4D0B81B31657473100DEF560 /* PBXTargetDependency */,
|
188
|
+
);
|
189
|
+
name = ExampleTests;
|
190
|
+
productName = ExampleTests;
|
191
|
+
productReference = 4D0B81AD1657473100DEF560 /* ExampleTests.octest */;
|
192
|
+
productType = "com.apple.product-type.bundle";
|
193
|
+
};
|
194
|
+
/* End PBXNativeTarget section */
|
195
|
+
|
196
|
+
/* Begin PBXProject section */
|
197
|
+
4D0B81831657473000DEF560 /* Project object */ = {
|
198
|
+
isa = PBXProject;
|
199
|
+
attributes = {
|
200
|
+
CLASSPREFIX = Example;
|
201
|
+
LastUpgradeCheck = 0450;
|
202
|
+
ORGANIZATIONNAME = Example;
|
203
|
+
};
|
204
|
+
buildConfigurationList = 4D0B81861657473000DEF560 /* Build configuration list for PBXProject "Example" */;
|
205
|
+
compatibilityVersion = "Xcode 3.2";
|
206
|
+
developmentRegion = English;
|
207
|
+
hasScannedForEncodings = 0;
|
208
|
+
knownRegions = (
|
209
|
+
en,
|
210
|
+
);
|
211
|
+
mainGroup = 4D0B81811657473000DEF560;
|
212
|
+
productRefGroup = 4D0B818D1657473000DEF560 /* Products */;
|
213
|
+
projectDirPath = "";
|
214
|
+
projectRoot = "";
|
215
|
+
targets = (
|
216
|
+
4D0B818B1657473000DEF560 /* Example */,
|
217
|
+
4D0B81AC1657473100DEF560 /* ExampleTests */,
|
218
|
+
);
|
219
|
+
};
|
220
|
+
/* End PBXProject section */
|
221
|
+
|
222
|
+
/* Begin PBXResourcesBuildPhase section */
|
223
|
+
4D0B818A1657473000DEF560 /* Resources */ = {
|
224
|
+
isa = PBXResourcesBuildPhase;
|
225
|
+
buildActionMask = 2147483647;
|
226
|
+
files = (
|
227
|
+
4D0B819B1657473000DEF560 /* InfoPlist.strings in Resources */,
|
228
|
+
4D0B81A31657473000DEF560 /* Default.png in Resources */,
|
229
|
+
4D0B81A51657473000DEF560 /* Default@2x.png in Resources */,
|
230
|
+
4D0B81A71657473000DEF560 /* Default-568h@2x.png in Resources */,
|
231
|
+
);
|
232
|
+
runOnlyForDeploymentPostprocessing = 0;
|
233
|
+
};
|
234
|
+
4D0B81AA1657473100DEF560 /* Resources */ = {
|
235
|
+
isa = PBXResourcesBuildPhase;
|
236
|
+
buildActionMask = 2147483647;
|
237
|
+
files = (
|
238
|
+
4D0B81B91657473100DEF560 /* InfoPlist.strings in Resources */,
|
239
|
+
);
|
240
|
+
runOnlyForDeploymentPostprocessing = 0;
|
241
|
+
};
|
242
|
+
/* End PBXResourcesBuildPhase section */
|
243
|
+
|
244
|
+
/* Begin PBXShellScriptBuildPhase section */
|
245
|
+
4D0B81AB1657473100DEF560 /* ShellScript */ = {
|
246
|
+
isa = PBXShellScriptBuildPhase;
|
247
|
+
buildActionMask = 2147483647;
|
248
|
+
files = (
|
249
|
+
);
|
250
|
+
inputPaths = (
|
251
|
+
);
|
252
|
+
outputPaths = (
|
253
|
+
);
|
254
|
+
runOnlyForDeploymentPostprocessing = 0;
|
255
|
+
shellPath = /bin/sh;
|
256
|
+
shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
|
257
|
+
};
|
258
|
+
/* End PBXShellScriptBuildPhase section */
|
259
|
+
|
260
|
+
/* Begin PBXSourcesBuildPhase section */
|
261
|
+
4D0B81881657473000DEF560 /* Sources */ = {
|
262
|
+
isa = PBXSourcesBuildPhase;
|
263
|
+
buildActionMask = 2147483647;
|
264
|
+
files = (
|
265
|
+
4D0B819D1657473000DEF560 /* main.m in Sources */,
|
266
|
+
4D0B81A11657473000DEF560 /* ExampleAppDelegate.m in Sources */,
|
267
|
+
);
|
268
|
+
runOnlyForDeploymentPostprocessing = 0;
|
269
|
+
};
|
270
|
+
4D0B81A81657473100DEF560 /* Sources */ = {
|
271
|
+
isa = PBXSourcesBuildPhase;
|
272
|
+
buildActionMask = 2147483647;
|
273
|
+
files = (
|
274
|
+
4D0B81BC1657473100DEF560 /* ExampleTests.m in Sources */,
|
275
|
+
);
|
276
|
+
runOnlyForDeploymentPostprocessing = 0;
|
277
|
+
};
|
278
|
+
/* End PBXSourcesBuildPhase section */
|
279
|
+
|
280
|
+
/* Begin PBXTargetDependency section */
|
281
|
+
4D0B81B31657473100DEF560 /* PBXTargetDependency */ = {
|
282
|
+
isa = PBXTargetDependency;
|
283
|
+
target = 4D0B818B1657473000DEF560 /* Example */;
|
284
|
+
targetProxy = 4D0B81B21657473100DEF560 /* PBXContainerItemProxy */;
|
285
|
+
};
|
286
|
+
/* End PBXTargetDependency section */
|
287
|
+
|
288
|
+
/* Begin PBXVariantGroup section */
|
289
|
+
4D0B81991657473000DEF560 /* InfoPlist.strings */ = {
|
290
|
+
isa = PBXVariantGroup;
|
291
|
+
children = (
|
292
|
+
4D0B819A1657473000DEF560 /* en */,
|
293
|
+
);
|
294
|
+
name = InfoPlist.strings;
|
295
|
+
sourceTree = "<group>";
|
296
|
+
};
|
297
|
+
4D0B81B71657473100DEF560 /* InfoPlist.strings */ = {
|
298
|
+
isa = PBXVariantGroup;
|
299
|
+
children = (
|
300
|
+
4D0B81B81657473100DEF560 /* en */,
|
301
|
+
);
|
302
|
+
name = InfoPlist.strings;
|
303
|
+
sourceTree = "<group>";
|
304
|
+
};
|
305
|
+
/* End PBXVariantGroup section */
|
306
|
+
|
307
|
+
/* Begin XCBuildConfiguration section */
|
308
|
+
4D0B81BD1657473100DEF560 /* Debug */ = {
|
309
|
+
isa = XCBuildConfiguration;
|
310
|
+
buildSettings = {
|
311
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
312
|
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
313
|
+
CLANG_CXX_LIBRARY = "libc++";
|
314
|
+
CLANG_ENABLE_OBJC_ARC = YES;
|
315
|
+
CLANG_WARN_EMPTY_BODY = YES;
|
316
|
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
317
|
+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
318
|
+
COPY_PHASE_STRIP = NO;
|
319
|
+
GCC_C_LANGUAGE_STANDARD = gnu99;
|
320
|
+
GCC_DYNAMIC_NO_PIC = NO;
|
321
|
+
GCC_OPTIMIZATION_LEVEL = 0;
|
322
|
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
323
|
+
"DEBUG=1",
|
324
|
+
"$(inherited)",
|
325
|
+
);
|
326
|
+
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
327
|
+
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
328
|
+
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
329
|
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
330
|
+
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
331
|
+
ONLY_ACTIVE_ARCH = YES;
|
332
|
+
SDKROOT = iphoneos;
|
333
|
+
};
|
334
|
+
name = Debug;
|
335
|
+
};
|
336
|
+
4D0B81BE1657473100DEF560 /* Release */ = {
|
337
|
+
isa = XCBuildConfiguration;
|
338
|
+
buildSettings = {
|
339
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
340
|
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
341
|
+
CLANG_CXX_LIBRARY = "libc++";
|
342
|
+
CLANG_ENABLE_OBJC_ARC = YES;
|
343
|
+
CLANG_WARN_EMPTY_BODY = YES;
|
344
|
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
345
|
+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
346
|
+
COPY_PHASE_STRIP = YES;
|
347
|
+
GCC_C_LANGUAGE_STANDARD = gnu99;
|
348
|
+
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
349
|
+
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
350
|
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
351
|
+
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
352
|
+
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
353
|
+
SDKROOT = iphoneos;
|
354
|
+
VALIDATE_PRODUCT = YES;
|
355
|
+
};
|
356
|
+
name = Release;
|
357
|
+
};
|
358
|
+
4D0B81C01657473100DEF560 /* Debug */ = {
|
359
|
+
isa = XCBuildConfiguration;
|
360
|
+
buildSettings = {
|
361
|
+
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
362
|
+
GCC_PREFIX_HEADER = "Example/Example-Prefix.pch";
|
363
|
+
INFOPLIST_FILE = "Example/Example-Info.plist";
|
364
|
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
365
|
+
WRAPPER_EXTENSION = app;
|
366
|
+
};
|
367
|
+
name = Debug;
|
368
|
+
};
|
369
|
+
4D0B81C11657473100DEF560 /* Release */ = {
|
370
|
+
isa = XCBuildConfiguration;
|
371
|
+
buildSettings = {
|
372
|
+
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
373
|
+
GCC_PREFIX_HEADER = "Example/Example-Prefix.pch";
|
374
|
+
INFOPLIST_FILE = "Example/Example-Info.plist";
|
375
|
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
376
|
+
WRAPPER_EXTENSION = app;
|
377
|
+
};
|
378
|
+
name = Release;
|
379
|
+
};
|
380
|
+
4D0B81C31657473100DEF560 /* Debug */ = {
|
381
|
+
isa = XCBuildConfiguration;
|
382
|
+
buildSettings = {
|
383
|
+
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Example.app/Example";
|
384
|
+
FRAMEWORK_SEARCH_PATHS = (
|
385
|
+
"\"$(SDKROOT)/Developer/Library/Frameworks\"",
|
386
|
+
"\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
|
387
|
+
);
|
388
|
+
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
389
|
+
GCC_PREFIX_HEADER = "Example/Example-Prefix.pch";
|
390
|
+
INFOPLIST_FILE = "ExampleTests/ExampleTests-Info.plist";
|
391
|
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
392
|
+
TEST_HOST = "$(BUNDLE_LOADER)";
|
393
|
+
WRAPPER_EXTENSION = octest;
|
394
|
+
};
|
395
|
+
name = Debug;
|
396
|
+
};
|
397
|
+
4D0B81C41657473100DEF560 /* Release */ = {
|
398
|
+
isa = XCBuildConfiguration;
|
399
|
+
buildSettings = {
|
400
|
+
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Example.app/Example";
|
401
|
+
FRAMEWORK_SEARCH_PATHS = (
|
402
|
+
"\"$(SDKROOT)/Developer/Library/Frameworks\"",
|
403
|
+
"\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
|
404
|
+
);
|
405
|
+
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
406
|
+
GCC_PREFIX_HEADER = "Example/Example-Prefix.pch";
|
407
|
+
INFOPLIST_FILE = "ExampleTests/ExampleTests-Info.plist";
|
408
|
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
409
|
+
TEST_HOST = "$(BUNDLE_LOADER)";
|
410
|
+
WRAPPER_EXTENSION = octest;
|
411
|
+
};
|
412
|
+
name = Release;
|
413
|
+
};
|
414
|
+
/* End XCBuildConfiguration section */
|
415
|
+
|
416
|
+
/* Begin XCConfigurationList section */
|
417
|
+
4D0B81861657473000DEF560 /* Build configuration list for PBXProject "Example" */ = {
|
418
|
+
isa = XCConfigurationList;
|
419
|
+
buildConfigurations = (
|
420
|
+
4D0B81BD1657473100DEF560 /* Debug */,
|
421
|
+
4D0B81BE1657473100DEF560 /* Release */,
|
422
|
+
);
|
423
|
+
defaultConfigurationIsVisible = 0;
|
424
|
+
defaultConfigurationName = Release;
|
425
|
+
};
|
426
|
+
4D0B81BF1657473100DEF560 /* Build configuration list for PBXNativeTarget "Example" */ = {
|
427
|
+
isa = XCConfigurationList;
|
428
|
+
buildConfigurations = (
|
429
|
+
4D0B81C01657473100DEF560 /* Debug */,
|
430
|
+
4D0B81C11657473100DEF560 /* Release */,
|
431
|
+
);
|
432
|
+
defaultConfigurationIsVisible = 0;
|
433
|
+
};
|
434
|
+
4D0B81C21657473100DEF560 /* Build configuration list for PBXNativeTarget "ExampleTests" */ = {
|
435
|
+
isa = XCConfigurationList;
|
436
|
+
buildConfigurations = (
|
437
|
+
4D0B81C31657473100DEF560 /* Debug */,
|
438
|
+
4D0B81C41657473100DEF560 /* Release */,
|
439
|
+
);
|
440
|
+
defaultConfigurationIsVisible = 0;
|
441
|
+
};
|
442
|
+
/* End XCConfigurationList section */
|
443
|
+
};
|
444
|
+
rootObject = 4D0B81831657473000DEF560 /* Project object */;
|
445
|
+
}
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "tempfile"
|
3
|
+
require "test/unit"
|
4
|
+
require "pbxplorer"
|
5
|
+
|
6
|
+
class XCProjectFileTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@pf = XCProjectFile.new "test"
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_read
|
12
|
+
assert_not_nil @pf.project
|
13
|
+
assert_equal @pf.uuids.length, 63
|
14
|
+
assert_equal @pf.objects.length, 63
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_objects_of_class
|
18
|
+
assert_equal @pf.objects_of_class(PBXObject).length, 63
|
19
|
+
assert_equal @pf.objects_of_class(PBXBuildPhase).length, 7
|
20
|
+
assert_equal @pf.objects_of_class(PBXSourcesBuildPhase).length, 2
|
21
|
+
|
22
|
+
assert_equal @pf.objects_of_class(PBXFileReference).length, 19
|
23
|
+
objs = @pf.objects_of_class PBXFileReference, {"name" => "Foundation.framework"}
|
24
|
+
assert_equal objs.length, 1
|
25
|
+
assert_equal @pf.objects_of_class(PBXBuildFile, {"fileRef" => objs.first.uuid}).length, 2
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_objects_with_uuids
|
29
|
+
fr = @pf.objects_of_class(PBXFileReference, {"name" => "Foundation.framework"}).first
|
30
|
+
objs = @pf.objects_of_class(PBXBuildFile, {"fileRef" => fr.uuid})
|
31
|
+
uuids = objs.map {|obj| obj.uuid}
|
32
|
+
|
33
|
+
assert_equal @pf.objects_with_uuids(uuids).length, 2
|
34
|
+
uuids << "garbage"
|
35
|
+
assert_equal @pf.objects_with_uuids(uuids).length, 2
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_object_with_uuid
|
39
|
+
assert_not_nil @pf.object_with_uuid(@pf.project.uuid)
|
40
|
+
assert_nil @pf.object_with_uuid("garbage")
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_create_remove_object
|
44
|
+
obj = @pf.add_object PBXFileReference.new
|
45
|
+
assert_equal @pf.objects.length, 64
|
46
|
+
assert_not_nil @pf.object_with_uuid(obj.uuid)
|
47
|
+
|
48
|
+
@pf.remove_object obj
|
49
|
+
assert_equal @pf.objects.length, 63
|
50
|
+
assert_nil @pf.object_with_uuid(obj.uuid)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_add_remove_object
|
54
|
+
obj = PBXFileReference.new
|
55
|
+
@pf.add_object obj
|
56
|
+
assert_equal @pf.objects.length, 64
|
57
|
+
assert_not_nil @pf.object_with_uuid(obj.uuid)
|
58
|
+
|
59
|
+
@pf.remove_object obj
|
60
|
+
assert_equal @pf.objects.length, 63
|
61
|
+
assert_nil @pf.object_with_uuid(obj.uuid)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_save
|
65
|
+
path = nil
|
66
|
+
Tempfile.open("test_save_") { |f| path = f.path }
|
67
|
+
@pf.save path
|
68
|
+
new_pf = XCProjectFile.new path
|
69
|
+
|
70
|
+
assert_not_nil new_pf
|
71
|
+
assert_equal @pf.objects.length, new_pf.objects.length
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_edit_save
|
75
|
+
path = nil
|
76
|
+
Tempfile.open("test_save_") { |f| path = f.path }
|
77
|
+
|
78
|
+
obj = @pf.add_object PBXFileReference.new
|
79
|
+
@pf.save path
|
80
|
+
|
81
|
+
old_pf = XCProjectFile.new "test"
|
82
|
+
new_pf = XCProjectFile.new path
|
83
|
+
|
84
|
+
assert_not_nil new_pf
|
85
|
+
assert_equal (old_pf.objects.length + 1), new_pf.objects.length
|
86
|
+
assert_nil old_pf.object_with_uuid obj.uuid
|
87
|
+
assert_not_nil new_pf.object_with_uuid obj.uuid
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_remove_file_ref
|
91
|
+
path = nil
|
92
|
+
Tempfile.open("test_save_") { |f| path = f.path }
|
93
|
+
|
94
|
+
fr = @pf.objects_of_class(PBXFileReference, {"name" => "Foundation.framework"}).first
|
95
|
+
bfs = @pf.objects_of_class(PBXBuildFile, {"fileRef" => fr.uuid})
|
96
|
+
@pf.remove_file_ref fr
|
97
|
+
@pf.save path
|
98
|
+
|
99
|
+
old_pf = XCProjectFile.new "test"
|
100
|
+
new_pf = XCProjectFile.new path
|
101
|
+
|
102
|
+
assert_not_nil new_pf
|
103
|
+
assert_equal (old_pf.objects.length - 3), new_pf.objects.length
|
104
|
+
(bfs + [fr]).each do |obj|
|
105
|
+
assert_not_nil old_pf.object_with_uuid obj.uuid
|
106
|
+
assert_nil new_pf.object_with_uuid obj.uuid
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class PBXProjectTest < Test::Unit::TestCase
|
112
|
+
def setup
|
113
|
+
@project = XCProjectFile.new("test").project
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_properties
|
117
|
+
assert_equal @project.targets.length, 2
|
118
|
+
assert_equal @project.build_configuration_list.uuid, "4D0B81861657473000DEF560"
|
119
|
+
assert_equal @project.main_group.uuid, "4D0B81811657473000DEF560"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class XCConfigurationListTest < Test::Unit::TestCase
|
124
|
+
def setup
|
125
|
+
@list = XCProjectFile.new("test").project.build_configuration_list
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_properties
|
129
|
+
assert_equal @list.build_configurations.length, 2
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pbxplorer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Mark Smith
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2013-03-19 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: pbxplorer is a set of Ruby classes for parsing, editing, and saving Xcode project (.pbxproj) files. It can also be used to explore the contents of a project using the interactive Ruby shell.
|
22
|
+
email: mark@camazotz.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- test/project.pbxproj
|
31
|
+
- test/test_pbxplorer.rb
|
32
|
+
- lib/pbxplorer.rb
|
33
|
+
- README.md
|
34
|
+
- Rakefile
|
35
|
+
- pbxplorer.gemspec
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/mjmsmith/pbxplorer
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
segments:
|
50
|
+
- 0
|
51
|
+
version: "0"
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.6
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: Xcode project file editor
|
66
|
+
test_files: []
|
67
|
+
|