Skip to content

Commit a312bdc

Browse files
authored
Merge pull request #7 from g-Off/xcode-10
Xcode 10
2 parents c4215ec + f93921c commit a312bdc

26 files changed

+297
-255
lines changed

Sources/XcodeProject/Archiving/PBXPListArchiver.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ public final class PBXPListArchiver {
131131
}
132132

133133
final class ObjectVisitor {
134-
private var objectMap: [PBXObject.ID: PBXObject] = [:]
135-
private var visited = Set<PBXObject.ID>()
134+
private var objectMap: [PBXGlobalID: PBXObject] = [:]
135+
private var visited = Set<PBXGlobalID>()
136136

137137
func visit(object: PBXObject?, where predicate: @escaping (_ object: PBXObject) -> Bool = { _ in return true}) {
138138
guard let object = object else { return }

Sources/XcodeProject/Archiving/PBXPListUnarchiver.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ class ObjectCache {
1919
self.types = types
2020
}
2121

22-
internal var objects: [PBXObject.ID: PBXObject] = [:]
22+
internal var objects: [PBXGlobalID: PBXObject] = [:]
2323

24-
func object<T: PBXObject>(for globalID: PBXObject.ID?) -> T? {
24+
func object<T: PBXObject>(for globalID: PBXGlobalID?) -> T? {
2525
guard let globalID = globalID else { return nil }
2626
return cached(globalID: globalID, create: true) as? T
2727
}
2828

29-
private func cached(globalID: PBXObject.ID, create: Bool = false) -> PBXObject? {
29+
private func cached(globalID: PBXGlobalID, create: Bool = false) -> PBXObject? {
3030
if let existing = objects[globalID] {
3131
return existing
3232
} else if create {
@@ -35,7 +35,7 @@ class ObjectCache {
3535
return nil
3636
}
3737

38-
private func createObject(globalID: PBXObject.ID) -> PBXObject? {
38+
private func createObject(globalID: PBXGlobalID) -> PBXObject? {
3939
guard let objectPlist = plist[globalID.rawValue] as? [String: Any] else { return nil }
4040
guard let isa = objectPlist["isa"] as? String else { fatalError() }
4141

@@ -51,7 +51,7 @@ class ObjectCache {
5151
return object
5252
}
5353

54-
private func setCached(object: PBXObject?, for globalID: PBXObject.ID) {
54+
private func setCached(object: PBXObject?, for globalID: PBXGlobalID) {
5555
guard let object = object else {
5656
return
5757
}

Sources/XcodeProject/Objects+Extensions/PBXGroup+FolderSync.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ public extension PBXGroup {
2727
currentGroup = currentGroup.addGroup(pathComponent: $0)
2828
}
2929
}
30-
let fileReference = PBXFileReference(globalID: PBXObject.ID(), path: filePathComponents.last)
30+
let fileReference = PBXFileReference(globalID: PBXGlobalID(), path: filePathComponents.last)
3131
currentGroup.add(child: fileReference)
3232
return fileReference
3333
}
3434

3535
@discardableResult
3636
func addGroup(pathComponent: String) -> PBXGroup {
37-
let group = PBXGroup(globalID: PBXObject.ID(), name: nil, path: pathComponent, sourceTree: .group)
37+
let group = PBXGroup(globalID: PBXGlobalID(), name: nil, path: pathComponent, sourceTree: .group)
3838
children.append(group)
3939
return group
4040
}

Sources/XcodeProject/Objects+Extensions/PBXProject+Helpers.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
//
88

99
public extension PBXProject {
10-
func generateGlobalId() -> PBXObject.ID {
11-
var objectId = PBXObject.ID()
10+
func generateGlobalId() -> PBXGlobalID {
11+
var objectId = PBXGlobalID()
1212
while objects[objectId] != nil {
13-
objectId = PBXObject.ID()
13+
objectId = PBXGlobalID()
1414
}
1515
return objectId
1616
}

Sources/XcodeProject/Objects/Build Phases/PBXBuildPhase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public class PBXBuildPhase: PBXObject {
5959
}
6060
self._name = plist["name"]?.string
6161
self.files = files.compactMap {
62-
let file: PBXBuildFile? = objectCache.object(for: PBXObject.ID(rawValue: $0))
62+
let file: PBXBuildFile? = objectCache.object(for: PBXGlobalID(rawValue: $0))
6363
return file
6464
}
6565

Sources/XcodeProject/Objects/PBXBuildFile.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ public final class PBXBuildFile: PBXObject {
2020
}
2121
var settings: [String: Any]?
2222

23-
public convenience init(globalID: PBXObject.ID, fileReference: PBXReference) {
23+
public convenience init(globalID: PBXGlobalID, fileReference: PBXReference) {
2424
self.init(globalID: globalID)
2525
fileRef = fileReference
2626
}
2727

2828
override func update(with plist: PropertyList, objectCache: ObjectCache) {
2929
super.update(with: plist, objectCache: objectCache)
30-
self.fileRef = objectCache.object(for: PBXObject.ID(rawValue: plist["fileRef"]?.string))
30+
self.fileRef = objectCache.object(for: PBXGlobalID(rawValue: plist["fileRef"]?.string))
3131
self.settings = plist["settings"]?.dictionary
3232
}
3333

Sources/XcodeProject/Objects/PBXContainerItemProxy.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ final class PBXContainerItemProxy: PBXObject {
2626
super.update(with: plist, objectCache: objectCache)
2727

2828
guard
29-
let containerPortal = objectCache.object(for: PBXObject.ID(rawValue: plist["containerPortal"]?.string)),
29+
let containerPortal = objectCache.object(for: PBXGlobalID(rawValue: plist["containerPortal"]?.string)),
3030
let proxyType = ProxyType(string: plist["proxyType"]?.string),
3131
let remoteGlobalIDString = plist["remoteGlobalIDString"]?.string,
3232
let remoteInfo = plist["remoteInfo"]?.string
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//
2+
// PBXGlobalID+Generator.swift
3+
// XcodeProject
4+
//
5+
// Created by Geoffrey Foster on 2018-12-02.
6+
//
7+
8+
import Foundation
9+
10+
extension PBXGlobalID {
11+
struct Generator {
12+
private struct GlobalIdentifier: CustomStringConvertible {
13+
let userHash: UInt8
14+
let pidByte: UInt8
15+
var random: UInt16
16+
var time: UInt32
17+
let zero: UInt8 = 0
18+
let hostShift: UInt8
19+
let hostHigh: UInt8
20+
let hostLow: UInt8
21+
22+
var description: String {
23+
let components = [
24+
userHash.hexRepresentation,
25+
pidByte.hexRepresentation,
26+
random.hexRepresentation,
27+
time.hexRepresentation,
28+
zero.hexRepresentation,
29+
hostShift.hexRepresentation,
30+
hostHigh.hexRepresentation,
31+
hostLow.hexRepresentation,
32+
]
33+
return components.joined()
34+
}
35+
}
36+
37+
private var gid: GlobalIdentifier
38+
39+
private var randomSequence: UInt16 = 0
40+
private let referenceDateGenerator: () -> Date
41+
42+
private var lastTime: UInt32 = 0
43+
private var firstSequence: UInt16 = 0
44+
45+
init(userName: String = NSUserName(), processId: pid_t = getpid(), random: inout RandomNumberGenerator, referenceDateGenerator: @escaping () -> Date = Generator.referenceDate) {
46+
self.referenceDateGenerator = referenceDateGenerator
47+
48+
var hostId: UInt32 = UInt32(gethostid())
49+
if hostId == 0 {
50+
hostId = random.next()
51+
}
52+
self.gid = GlobalIdentifier(
53+
userHash: Generator.userHash(userName: userName),
54+
pidByte: UInt8(truncatingIfNeeded: processId),
55+
random: random.next(),
56+
time: 0,
57+
hostShift: UInt8(truncatingIfNeeded: (hostId >> 0x10) & 0xff),
58+
hostHigh: UInt8(truncatingIfNeeded: (hostId & 0xff00) >> 0x8),
59+
hostLow: UInt8(truncatingIfNeeded: hostId & 0xff)
60+
)
61+
}
62+
63+
mutating func next() -> String {
64+
let randomValue = gid.random + 1
65+
66+
let time = UInt32(referenceDateGenerator().timeIntervalSinceReferenceDate)
67+
if time > lastTime {
68+
firstSequence = randomValue
69+
lastTime = time
70+
} else if firstSequence == randomValue {
71+
lastTime += 1
72+
}
73+
74+
gid.random = randomValue
75+
gid.time = lastTime
76+
77+
return gid.description
78+
}
79+
80+
static func referenceDate() -> Date {
81+
return Date()
82+
}
83+
84+
static func userHash(userName: String) -> UInt8 {
85+
func hash(character: UnicodeScalar) -> UInt32 {
86+
let uppercaseA: UnicodeScalar = "A"
87+
let uppercaseZ: UnicodeScalar = "Z"
88+
let lowercaseA: UnicodeScalar = "a"
89+
let zero: UnicodeScalar = "0"
90+
switch character {
91+
case "A"..."Z":
92+
return character.value - uppercaseA.value
93+
case "a"..."z":
94+
return character.value - lowercaseA.value
95+
case "0"..."9":
96+
return uppercaseZ.value - uppercaseA.value + 1 + (UInt32(character.value - zero.value) % 5)
97+
default:
98+
return 31
99+
}
100+
}
101+
102+
var userHash: UInt32 = 0
103+
var hashValue: UInt32 = 0
104+
userName.unicodeScalars.map { hash(character: $0) }.forEach {
105+
var h = $0
106+
if h != 0 {
107+
h = ((h << hashValue) >> 8) | (h << hashValue)
108+
}
109+
hashValue = (hashValue + 5) & 7
110+
userHash = userHash ^ h
111+
}
112+
return UInt8(truncatingIfNeeded: userHash)
113+
}
114+
}
115+
}
116+
117+
extension BinaryInteger {
118+
var hexRepresentation: String {
119+
let hex = String(self, radix: 16, uppercase: true)
120+
let byteCount = bitWidth / 4
121+
let padding = max(byteCount - hex.count, 0)
122+
return String(repeating: "0", count: padding) + hex
123+
}
124+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// PBXGlobalID.swift
3+
// XcodeProject
4+
//
5+
// Created by Geoffrey Foster on 2018-12-02.
6+
//
7+
8+
import Foundation
9+
10+
public struct PBXGlobalID: RawRepresentable {
11+
public let rawValue: String
12+
13+
public init(rawValue: String) {
14+
self.rawValue = rawValue
15+
}
16+
17+
public init?(rawValue: String?) {
18+
guard let rawValue = rawValue else { return nil }
19+
self.init(rawValue: rawValue)
20+
}
21+
22+
public init() {
23+
self.rawValue = PBXGlobalID.generator.next()
24+
}
25+
26+
static func ids(from strings: [String]?) -> [PBXGlobalID]? {
27+
return strings?.compactMap { return PBXGlobalID(rawValue: $0) }
28+
}
29+
30+
private static var randomNumberGenerator: RandomNumberGenerator = SystemRandomNumberGenerator()
31+
private static var generator: PBXGlobalID.Generator = PBXGlobalID.Generator(random: &randomNumberGenerator)
32+
}
33+
34+
extension PBXGlobalID: Hashable {
35+
public var hashValue: Int {
36+
return rawValue.hashValue
37+
}
38+
39+
public static func ==(lhs: PBXGlobalID, rhs: PBXGlobalID) -> Bool {
40+
return lhs.rawValue == rhs.rawValue
41+
}
42+
}
43+
44+
extension PBXGlobalID: Comparable {
45+
public static func <(lhs: PBXGlobalID, rhs: PBXGlobalID) -> Bool {
46+
return lhs.rawValue < rhs.rawValue
47+
}
48+
}
49+
50+
extension PropertyList {
51+
var globalID: PBXGlobalID? {
52+
return PBXGlobalID(rawValue: self.string)
53+
}
54+
}

0 commit comments

Comments
 (0)