Skip to content

Commit 87292db

Browse files
author
Sheen
committed
STRFRAMEWORK-1674: Plist2Swift source modified
1 parent 9ed78f4 commit 87292db

1 file changed

Lines changed: 134 additions & 29 deletions

File tree

Plist2swift/Plist2swift.swift

Lines changed: 134 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,72 @@ private func generateHeader() {
8383
""")
8484
}
8585

86+
/**
87+
Checking the key is present in the Optional Dictionary
88+
*/
89+
private func isKeyPresentInOptionalDictionary(keyToSearch: String, tupleKey: String, optionalDictionary: [String: [String: String]]) -> Bool {
90+
guard let optionalKeysAndTypes = optionalDictionary[keyToSearch] else {
91+
return false
92+
}
93+
94+
let optionalArray = optionalKeysAndTypes.keys
95+
return optionalArray.contains(tupleKey)
96+
}
97+
98+
/**
99+
Checking the key is present in all the plists
100+
*/
101+
private func isKeyAvailableInAllPlists(keyToSearch: String, tupleKey: String, tuplesForPlists: [String: KeyValueTuples]) -> Bool {
102+
let plistPaths = tuplesForPlists.keys
103+
for plistPath in plistPaths {
104+
105+
guard let tuples = tuplesForPlists[plistPath] else {
106+
return false
107+
}
108+
109+
guard let dictionary = tuples[tupleKey] as? Dictionary<String, Any> else {
110+
return false
111+
}
112+
113+
if (dictionary.keys.contains(keyToSearch) == false) {
114+
return false
115+
}
116+
}
117+
118+
return true
119+
}
120+
121+
/**
122+
Generate Protocol for the Tuples and return the optional dictionary
123+
*/
124+
private func generateProtocol(tuplesForPlists: [String: KeyValueTuples], allKeyValueTuples: [String: KeyValueTuples]) -> [String: [String: String]] {
125+
var optionalDictionary: [String: [String: String]] = [:]
126+
for (tupleKey, tuples) in allKeyValueTuples {
127+
128+
let name = tupleKey.uppercaseFirst()
129+
let protocolName = name.appending("Protocol")
130+
print("protocol \(protocolName) {")
131+
intend()
132+
133+
var optionalKeysAndTypes: [String: String] = [:]
134+
for tuple in tuples.tuples {
135+
let isOptional = !(isKeyAvailableInAllPlists(keyToSearch: tuple.key, tupleKey: tupleKey, tuplesForPlists: tuplesForPlists))
136+
var type = typeForValue(tuple.value as Any)
137+
if (isOptional == true) {
138+
type = "\(type)?"
139+
optionalKeysAndTypes[tuple.key] = type
140+
}
141+
142+
print("\(tabs())var \(tuple.key.lowercaseFirst()): \(type) { get }")
143+
}
144+
145+
optionalDictionary[tupleKey] = optionalKeysAndTypes
146+
print("\(tabs(intendBy: -1))}\n")
147+
}
148+
149+
return optionalDictionary
150+
}
151+
86152
/**
87153
Generates a protocol with public instance properties. Used to generate protocols that internal structs conform to.
88154

@@ -157,11 +223,11 @@ Generate structs out of Dictionaries and make them conform to a given protocol.
157223
- protocolName: Name of the protocol; It has to end with a "Protocol" suffix; Default is 'nil' - the new generated protocol will be used
158224

159225
*/
160-
private func generateStructs(name structName: String? = nil, tuples: KeyValueTuples, keysAndTypes: [String: String]? = nil, oddKeys: [String], protocolName: String? = nil) {
226+
private func generateStructs(name key: String? = nil, tuples: KeyValueTuples, keysAndTypes: [String: String]? = nil, oddKeys: [String], protocolName: String? = nil, optionalDictionary: [String: [String: String]]) {
161227
var configName: String? = tuples[configurationKeyName] as? String
162228

163-
if (configName == nil && structName != nil) {
164-
configName = structName?.uppercaseFirst()
229+
if (configName == nil && key != nil) {
230+
configName = key
165231
}
166232

167233
guard var structName = configName else {
@@ -207,45 +273,80 @@ private func generateStructs(name structName: String? = nil, tuples: KeyValueTup
207273
print("\n\(tabs())internal struct \(structName)\(conformingToProtocol) {")
208274
intend()
209275

276+
var availableKeys: [String] = []
210277
for tuple in tuples.tuples {
211278

212-
let key = tuple.key
213-
let value = tuple.value
279+
let tupleKey = tuple.key
280+
let tupleValue = tuple.value
281+
availableKeys.append(tupleKey)
214282

215-
if (oddKeys.contains(key)) {
283+
if (oddKeys.contains(tupleKey)) {
216284
continue
217285
}
218286

219-
guard let type = localKeysAndTypes?[key] else {
287+
guard let type = localKeysAndTypes?[tupleKey] else {
220288
return
221289
}
222290

291+
let isOptional: Bool = {
292+
guard let key = key else {
293+
return false
294+
}
295+
296+
return isKeyPresentInOptionalDictionary(keyToSearch: key, tupleKey: tupleKey, optionalDictionary: optionalDictionary)
297+
}()
298+
223299
switch type {
224-
case "String":
225-
print("\(tabs())internal let \(key.lowercaseFirst()): \(type) = \"\(value)\"")
226-
case "Int":
227-
print("\(tabs())internal let \(key.lowercaseFirst()): \(type) = \(value)")
228-
case "Bool":
229-
let boolString = (((value as? Bool) == true) ? "true" : "false")
230-
print("\(tabs())internal let \(key.lowercaseFirst()): \(type) = \(boolString)")
231-
case "Array<Any>":
232-
let arrayValue = value as! Array<String>
233-
print("\(tabs())internal let \(key.lowercaseFirst()): \(type) = \(arrayValue)")
300+
case "String" where (isOptional == false):
301+
print("\(tabs())internal let \(tupleKey.lowercaseFirst()): \(type) = \"\(tupleValue)\"")
302+
case "String" where (isOptional == true):
303+
print("\(tabs())internal var \(tupleKey.lowercaseFirst()): \(type)? = \"\(tupleValue)\"")
304+
case "Int" where (isOptional == false):
305+
print("\(tabs())internal let \(tupleKey.lowercaseFirst()): \(type) = \(tupleValue)")
306+
case "Int" where (isOptional == true):
307+
print("\(tabs())internal var \(tupleKey.lowercaseFirst()): \(type)? = \(tupleValue)")
308+
case "Bool" where (isOptional == false):
309+
let boolString = (((tupleValue as? Bool) == true) ? "true" : "false")
310+
print("\(tabs())internal let \(tupleKey.lowercaseFirst()): \(type) = \(boolString)")
311+
case "Bool" where (isOptional == true):
312+
let boolString = (((tupleValue as? Bool) == true) ? "true" : "false")
313+
print("\(tabs())internal var \(tupleKey.lowercaseFirst()): \(type)? = \(boolString)")
314+
case "Array<Any>" where (isOptional == false):
315+
let arrayValue = tupleValue as! Array<String>
316+
print("\(tabs())internal let \(tupleKey.lowercaseFirst()): \(type) = \(arrayValue)")
317+
case "Array<Any>" where (isOptional == true):
318+
let arrayValue = tupleValue as! Array<String>
319+
print("\(tabs())internal var \(tupleKey.lowercaseFirst()): \(type)? = \(arrayValue)")
234320
default:
235321
// default is a struct
236322
// Generate struct from the Dictionaries and Protocols
237323
if (type.contains("Protocol")) {
238-
let dictionary = tuples[key] as? Dictionary<String, Any>
324+
let dictionary = tuples[tupleKey] as? Dictionary<String, Any>
239325
let sortedDictionary = dictionary?.sorted { (pairOne, pairTwo) -> Bool in
240326
return pairOne.key < pairTwo.key
241327
}
242328

243-
generateStructs(name: key.uppercaseFirst(), tuples: KeyValueTuples(tuples: sortedDictionary ?? []), oddKeys: oddKeys, protocolName: type)
329+
generateStructs(name: tupleKey, tuples: KeyValueTuples(tuples: sortedDictionary ?? []), oddKeys: oddKeys, protocolName: type, optionalDictionary: optionalDictionary)
244330

245-
print("\(tabs())internal let \(key.lowercaseFirst()): \(type) = \(key.uppercaseFirst())()")
331+
print("\(tabs())internal let \(tupleKey.lowercaseFirst()): \(type) = \(tupleKey.uppercaseFirst())()")
246332
}
333+
247334
}
248335
}
336+
337+
guard let key = key, let optionalKeysAndTypes = optionalDictionary[key] else {
338+
print("\(tabs(intendBy: -1))}\n")
339+
return
340+
}
341+
342+
let keysAndTypesToAdd = optionalKeysAndTypes.filter { (key: String, type: String) in
343+
return (availableKeys.contains(key) == false)
344+
}
345+
346+
for (key, type) in keysAndTypesToAdd {
347+
print("\(tabs())internal var \(key.lowercaseFirst()): \(type) = nil")
348+
}
349+
249350
print("\(tabs(intendBy: -1))}\n")
250351
}
251352

@@ -260,7 +361,7 @@ Generates extensions to structs, conforming to protocol
260361
- oddKeys: Keys to generate Optional properties from
261362

262363
*/
263-
private func generateExtensions(enumName: String, protocolName: String, allTuples: [KeyValueTuples], keysAndTypes: Dictionary<String, String>, oddKeys: [String]) {
364+
private func generateExtensions(enumName: String, protocolName: String, allTuples: [KeyValueTuples], keysAndTypes: Dictionary<String, String>, oddKeys: [String], optionalDictionary: [String: [String: String]]) {
264365
for tuples in allTuples {
265366

266367
guard let caseName = tuples[configurationKeyName] as? String else {
@@ -298,7 +399,7 @@ private func generateExtensions(enumName: String, protocolName: String, allTuple
298399
return pairOne.key < pairTwo.key
299400
}
300401

301-
generateStructs(name: oddKey.uppercaseFirst(), tuples: KeyValueTuples(tuples: sortedDictionary ?? []), oddKeys: oddKeys, protocolName: type)
402+
generateStructs(name: oddKey, tuples: KeyValueTuples(tuples: sortedDictionary ?? []), oddKeys: oddKeys, protocolName: type, optionalDictionary: optionalDictionary)
302403
print("\(tabs())var \(oddKey.lowercaseFirst()): \(type)? {")
303404
print("\(tabs(intendBy: 1))return \(oddKey.uppercaseFirst())()")
304405
print("\(tabs(intendBy: -1))}")
@@ -325,7 +426,7 @@ Generate an enum with structs and properties.
325426
- oddKeys: Keys to generate Optional properties from
326427

327428
*/
328-
private func generateEnum(name enumName: String, protocolName: String, allTuples: [KeyValueTuples], keysAndTypes: Dictionary<String, String>, oddKeys: [String]) {
429+
private func generateEnum(name enumName: String, protocolName: String, allTuples: [KeyValueTuples], keysAndTypes: Dictionary<String, String>, oddKeys: [String], optionalDictionary: [String: [String: String]]) {
329430

330431
let cases: [String] = allTuples.map { (tuples: KeyValueTuples) in
331432
return (tuples[configurationKeyName] as? String ?? "")
@@ -339,7 +440,7 @@ private func generateEnum(name enumName: String, protocolName: String, allTuples
339440
}
340441

341442
for tuples in allTuples {
342-
generateStructs(tuples: tuples, keysAndTypes: keysAndTypes, oddKeys: oddKeys)
443+
generateStructs(tuples: tuples, keysAndTypes: keysAndTypes, oddKeys: oddKeys, optionalDictionary: optionalDictionary)
343444
}
344445

345446
print("""
@@ -357,7 +458,7 @@ private func generateEnum(name enumName: String, protocolName: String, allTuples
357458
print("\(tabs())}")
358459
print("\(tabs(intendBy: -1))}")
359460
print("\(tabs(intendBy: -1))}\n")
360-
generateExtensions(enumName: enumName, protocolName: protocolName, allTuples: allTuples, keysAndTypes: keysAndTypes, oddKeys: oddKeys)
461+
generateExtensions(enumName: enumName, protocolName: protocolName, allTuples: allTuples, keysAndTypes: keysAndTypes, oddKeys: oddKeys, optionalDictionary: optionalDictionary)
361462
}
362463

363464
/**
@@ -497,7 +598,8 @@ var oddKeys = [String]()
497598
var keysAndTypes: [String:String] = [:]
498599
var allTuples: [KeyValueTuples] = []
499600
var protocolName: String = enumName.appending("Protocol")
500-
601+
var tuplesForPlists: [String: KeyValueTuples] = [:]
602+
var allKeyValueTuples: [String: KeyValueTuples] = [:]
501603
generateHeader()
502604

503605
// gather keys and values... and types
@@ -508,6 +610,7 @@ for plistPath in plists {
508610
exit(1)
509611
}
510612

613+
tuplesForPlists[plistPath] = tuples
511614
allTuples.append(tuples)
512615

513616
let allKeys = tuples.keys
@@ -537,8 +640,9 @@ for plistPath in plists {
537640
return pairOne.key < pairTwo.key
538641
}
539642

540-
let protocolName = generateProtocol(name: key.uppercaseFirst(), tuples: KeyValueTuples(tuples: sortedDictionary ?? []))
541-
// override type with new protocol
643+
allKeyValueTuples[key] = KeyValueTuples(tuples: sortedDictionary ?? [])
644+
let name = key.uppercaseFirst()
645+
let protocolName = name.appending("Protocol")
542646
keysAndTypes[key] = protocolName
543647
}
544648
}
@@ -553,5 +657,6 @@ for plistPath in plists {
553657
}
554658
}
555659

660+
let optionalDictionary = generateProtocol(tuplesForPlists: tuplesForPlists, allKeyValueTuples: allKeyValueTuples)
556661
generateProtocol(name: protocolName, commonKeys: commonKeys, oddKeys: oddKeys, keysAndTypes: keysAndTypes)
557-
generateEnum(name: enumName, protocolName: protocolName, allTuples: allTuples, keysAndTypes: keysAndTypes, oddKeys: oddKeys)
662+
generateEnum(name: enumName, protocolName: protocolName, allTuples: allTuples, keysAndTypes: keysAndTypes, oddKeys: oddKeys, optionalDictionary: optionalDictionary)

0 commit comments

Comments
 (0)