88
99import Foundation
1010
11- public class XcodeProj {
11+ open class PropertyList {
12+
13+ public enum Format {
14+ case binary
15+ case xml
16+ case json
17+ case openStep
18+
19+ public func toPropertyListformat( ) -> PropertyListSerialization . PropertyListFormat ? {
20+ switch self {
21+ case . binary:
22+ return . binary
23+ case . xml:
24+ return . xml
25+ case . openStep:
26+ return . openStep
27+ case . json:
28+ return nil
29+ }
30+ }
31+
32+ public init ( _ format: PropertyListSerialization . PropertyListFormat ) {
33+ switch format {
34+ case . binary:
35+ self = . binary
36+ case . xml:
37+ self = . xml
38+ case . openStep:
39+ self = . openStep
40+ }
41+ }
42+
43+ public init ? ( _ format: PropertyListSerialization . PropertyListFormat ? ) {
44+ if let format = format {
45+ self . init ( format)
46+ } else {
47+ return nil
48+ }
49+ }
50+ }
51+
52+ public let dict : PBXObject . Fields
53+ public let format : Format
54+
55+ public init ( dict: PBXObject . Fields , format: Format ) throws {
56+ self . dict = dict
57+ self . format = format
58+ }
59+
60+ public convenience init ( propertyListData data: Data ) throws {
61+ let format : Format
62+ let obj : Any
63+ if data. first == 123 { // start with {
64+ obj = try JSONSerialization . jsonObject ( with: data)
65+ format = . json
66+ } else {
67+ var propertyListFormat : PropertyListSerialization . PropertyListFormat = . binary
68+ obj = try PropertyListSerialization . propertyList ( from: data, options: [ ] , format: & propertyListFormat)
69+ format = . init( propertyListFormat)
70+ }
71+
72+ guard let dict = obj as? PBXObject . Fields else {
73+ throw XcodeProjError . invalidData ( object: obj)
74+ }
75+
76+ try self . init ( dict: dict, format: format)
77+ }
78+
79+ public convenience init ( url: URL ) throws {
80+ assert ( url. isFileURL)
81+ do {
82+ let data = try Data ( contentsOf: url)
83+ try self . init ( propertyListData: data)
84+ } catch let error as XcodeProjError {
85+ throw error
86+ } catch {
87+ throw XcodeProjError . failedToReadFile ( error: error)
88+ }
89+ }
90+
91+ }
92+
93+ public class XcodeProj : PropertyList {
1294
1395 public static let pbxprojFileExtension = " pbxproj "
1496 public static let pbxprojFileName = " project.pbxproj "
1597
16- public let dict : PBXObject . Fields
17- public let format : PropertyListSerialization . PropertyListFormat
1898 public var projectName : String = " PRODUCT_NAME "
1999 public var lineEnding : String = " \r \n "
20100
101+ public let objects : Objects
21102 public let project : PBXProject
22103
23104 public class Objects : PBXObjectFactory {
@@ -69,7 +150,6 @@ public class XcodeProj {
69150
70151 }
71152
72- public let objects : Objects
73153
74154 // MARK: init
75155 public convenience init ( url: URL ) throws {
@@ -112,35 +192,25 @@ public class XcodeProj {
112192 }
113193 }
114194
115- public convenience init ( propertyListData data: Data ) throws {
116- var format : PropertyListSerialization . PropertyListFormat = . binary
117- let obj = try PropertyListSerialization . propertyList ( from: data, options: [ ] , format: & format)
118-
119- guard let dict = obj as? PBXObject . Fields else {
120- throw XcodeProjError . invalidData ( object: obj)
121- }
122-
123- try self . init ( dict: dict, format: format)
195+ public convenience init ( dict: PBXObject . Fields , format: PropertyListSerialization . PropertyListFormat ) throws {
196+ try self . init ( dict: dict, format: . init( format) )
124197 }
125198
126- init ( dict: PBXObject . Fields , format: PropertyListSerialization . PropertyListFormat ) throws {
127- self . dict = dict
128- self . format = format
129-
199+ public override init ( dict: PBXObject . Fields , format: Format ) throws {
130200 self . objects = Objects ( )
131201
132- if let objs = self . dict [ FieldKey . objects. rawValue] as? [ String : PBXObject . Fields ] {
202+ if let objs = dict [ FieldKey . objects. rawValue] as? [ String : PBXObject . Fields ] {
133203 // Create all objects
134204 for (ref, obj) in objs {
135205 self . objects. dict [ ref] = try XcodeProj . createObject ( ref: ref, fields: obj, objects: self . objects)
136206 }
137207
138208 // parsing project
139- if let rootObjectRef = self . dict [ FieldKey . rootObject. rawValue] as? String {
209+ if let rootObjectRef = dict [ FieldKey . rootObject. rawValue] as? String {
140210 if let projDict = objs [ rootObjectRef] {
141211 self . project = PBXProject ( ref: rootObjectRef, fields: projDict, objects: self . objects)
142212 if let mainGroup = self . project. mainGroup {
143- objects. fullFilePaths = paths ( mainGroup, prefix: " " )
213+ objects. fullFilePaths = XcodeProj . paths ( mainGroup, prefix: " " )
144214 } else {
145215 if let mainGroupref = self . project. string ( PBXProject . PBXKeys. mainGroup) {
146216 throw XcodeProjError . objectMissing ( key: mainGroupref, expectedType: . group)
@@ -157,6 +227,7 @@ public class XcodeProj {
157227 } else {
158228 throw XcodeProjError . fieldKeyMissing ( . objects)
159229 }
230+ try super. init ( dict: dict, format: format)
160231 }
161232
162233 static func createObject( ref: String , fields: PBXObject . Fields , objects: XcodeProj . Objects ) throws -> PBXObject {
0 commit comments