Skip to content

Commit 3c0778f

Browse files
authored
Merge pull request #104 from smartmobilefactory/bugfix/optionals-generation-for-dictionary-subkeys
Plist2swift: Fix Generation of Sub-Keys in Dictionaries
2 parents a527e77 + 767449d commit 3c0778f

9 files changed

Lines changed: 121 additions & 15 deletions

File tree

Plist2swift/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
/*.xcodeproj
5+
xcuserdata/

Plist2swift/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Plist2swift/Package.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// swift-tools-version:5.1
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "Plist2swift",
8+
dependencies: [
9+
// Dependencies declare other packages that this package depends on.
10+
// .package(url: /* package url */, from: "1.0.0"),
11+
],
12+
targets: [
13+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
14+
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
15+
.target(
16+
name: "Plist2swift",
17+
dependencies: []),
18+
.testTarget(
19+
name: "Plist2swiftTests",
20+
dependencies: ["Plist2swift"]),
21+
]
22+
)

Plist2swift/Plist2swift

-104 KB
Binary file not shown.
Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#!/usr/bin/env xcrun --sdk macosx swift
2+
13
//
24
// main.swift
35
// plist2swift
@@ -620,22 +622,31 @@ for plistPath in plists {
620622
}
621623

622624
for key in allKeys {
623-
if (keysAndTypes[key] == nil) {
624-
let type = typeForValue(tuples[key]!)
625-
keysAndTypes[key] = type
626-
// Generate protocols for Dictionary entries
627-
if (type == "Dictionary<String, Any>") {
625+
guard let tuple = tuples[key] else {
626+
continue
627+
}
628628

629-
let dictionary = tuples[key] as? Dictionary<String, Any>
630-
let sortedDictionary = dictionary?.sorted { (pairOne, pairTwo) -> Bool in
631-
return pairOne.key < pairTwo.key
629+
let type = typeForValue(tuple)
630+
if (type != "Dictionary<String, Any>") { // Just register the existence of primitive types
631+
keysAndTypes[key] = type
632+
} else { // Generate protocols for Dictionary entries
633+
var dictionary = tuples[key] as? Dictionary<String, Any> ?? [:]
634+
635+
// Merge sub-keys in dictionaries from current property list with already known sub-keys from dictionaries
636+
// with the same name.
637+
if let keyValueTuples = allKeyValueTuples[key] {
638+
for knownKey in Set<String>(keyValueTuples.keys).subtracting(Set(dictionary.keys)) {
639+
for (tupleKey, tupleValue) in keyValueTuples.tuples {
640+
if (tupleKey == knownKey) {
641+
dictionary[tupleKey] = tupleValue
642+
}
643+
}
632644
}
633-
634-
allKeyValueTuples[key] = KeyValueTuples(tuples: sortedDictionary ?? [])
635-
let name = key.uppercaseFirst()
636-
let protocolName = name.appending("Protocol")
637-
keysAndTypes[key] = protocolName
638645
}
646+
647+
allKeyValueTuples[key] = KeyValueTuples(tuples: dictionary.sorted { $0.key < $1.key })
648+
// Generate protocol name
649+
keysAndTypes[key] = key.uppercaseFirst().appending("Protocol")
639650
}
640651
}
641652

Plist2swift/Tests/LinuxMain.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import XCTest
2+
3+
import Plist2swiftTests
4+
5+
var tests = [XCTestCaseEntry]()
6+
tests += Plist2swiftTests.allTests()
7+
XCTMain(tests)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import XCTest
2+
import class Foundation.Bundle
3+
4+
final class Plist2swiftTests: XCTestCase {
5+
func testExample() throws {
6+
// This is an example of a functional test case.
7+
// Use XCTAssert and related functions to verify your tests produce the correct
8+
// results.
9+
10+
// Some of the APIs that we use below are available in macOS 10.13 and above.
11+
guard #available(macOS 10.13, *) else {
12+
return
13+
}
14+
15+
let fooBinary = productsDirectory.appendingPathComponent("Plist2swift")
16+
17+
let process = Process()
18+
process.executableURL = fooBinary
19+
20+
let pipe = Pipe()
21+
process.standardOutput = pipe
22+
23+
try process.run()
24+
process.waitUntilExit()
25+
26+
let data = pipe.fileHandleForReading.readDataToEndOfFile()
27+
let output = String(data: data, encoding: .utf8)
28+
29+
XCTAssertEqual(output, "Hello, world!\n")
30+
}
31+
32+
/// Returns path to the built products directory.
33+
var productsDirectory: URL {
34+
#if os(macOS)
35+
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
36+
return bundle.bundleURL.deletingLastPathComponent()
37+
}
38+
fatalError("couldn't find the products directory")
39+
#else
40+
return Bundle.main.bundleURL
41+
#endif
42+
}
43+
44+
static var allTests = [
45+
("testExample", testExample),
46+
]
47+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import XCTest
2+
3+
#if !canImport(ObjectiveC)
4+
public func allTests() -> [XCTestCaseEntry] {
5+
return [
6+
testCase(Plist2swiftTests.allTests),
7+
]
8+
}
9+
#endif

Plist2swift/build.sh

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)