From 997b601f95ddb14c5b7aeffa111919c75139d377 Mon Sep 17 00:00:00 2001 From: Ricardo Nunez Date: Fri, 20 Oct 2023 17:03:17 -0700 Subject: [PATCH 1/3] Migrates to SPM --- Cartfile | 1 - Cartfile.resolved | 1 - iSimulator.xcodeproj/project.pbxproj | 60 ++++++++++++++++++---------- 3 files changed, 38 insertions(+), 24 deletions(-) delete mode 100644 Cartfile delete mode 100644 Cartfile.resolved diff --git a/Cartfile b/Cartfile deleted file mode 100644 index d9ee2de..0000000 --- a/Cartfile +++ /dev/null @@ -1 +0,0 @@ -github "Hearst-DD/ObjectMapper" == 4.2.0 diff --git a/Cartfile.resolved b/Cartfile.resolved deleted file mode 100644 index dd221b9..0000000 --- a/Cartfile.resolved +++ /dev/null @@ -1 +0,0 @@ -github "Hearst-DD/ObjectMapper" "4.2.0" diff --git a/iSimulator.xcodeproj/project.pbxproj b/iSimulator.xcodeproj/project.pbxproj index cb13667..0aaeaf4 100644 --- a/iSimulator.xcodeproj/project.pbxproj +++ b/iSimulator.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -28,28 +28,13 @@ 29B227BA1FBD7B9F00BDE5BF /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B227B91FBD7B9F00BDE5BF /* PreferencesViewController.swift */; }; 29B591981F581513006CDEC0 /* FileWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B591971F581513006CDEC0 /* FileWatch.swift */; }; 315A809D22C90616005C2493 /* AppGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 315A809C22C90616005C2493 /* AppGroup.swift */; }; - 3198339421A7F5FF004ADEE3 /* ObjectMapper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3198338821A7F5FE004ADEE3 /* ObjectMapper.framework */; }; - 3198339521A7F5FF004ADEE3 /* ObjectMapper.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3198338821A7F5FE004ADEE3 /* ObjectMapper.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 31CD6D0221B2817900E49DC0 /* RootLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31CD6D0121B2817900E49DC0 /* RootLink.swift */; }; 31CD6D0421B2942300E49DC0 /* ApplicationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31CD6D0321B2942300E49DC0 /* ApplicationCache.swift */; }; + 8CA3047E2AE34B8F008869B1 /* ObjectMapper in Frameworks */ = {isa = PBXBuildFile; productRef = 8CA3047D2AE34B8F008869B1 /* ObjectMapper */; }; CFDB43E0264BCE6E0075BDDC /* Cartfile in Resources */ = {isa = PBXBuildFile; fileRef = CFDB43DF264BCE6E0075BDDC /* Cartfile */; }; CFDB43E4264BD5E50075BDDC /* Cartfile.resolved in Resources */ = {isa = PBXBuildFile; fileRef = CFDB43E3264BD5E50075BDDC /* Cartfile.resolved */; }; /* End PBXBuildFile section */ -/* Begin PBXCopyFilesBuildPhase section */ - 3198338221A7F5D7004ADEE3 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3198339521A7F5FF004ADEE3 /* ObjectMapper.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 291157AD1FB5501C000EE94F /* DevcieMenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DevcieMenuItem.swift; sourceTree = ""; }; 29157C541F4D56400069BDB6 /* Shell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Shell.swift; sourceTree = ""; }; @@ -86,7 +71,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3198339421A7F5FF004ADEE3 /* ObjectMapper.framework in Frameworks */, + 8CA3047E2AE34B8F008869B1 /* ObjectMapper in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -193,13 +178,15 @@ 292EAD9C1F458B3D009FC1ED /* Sources */, 292EAD9D1F458B3D009FC1ED /* Frameworks */, 292EAD9E1F458B3D009FC1ED /* Resources */, - 3198338221A7F5D7004ADEE3 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( ); name = iSimulator; + packageProductDependencies = ( + 8CA3047D2AE34B8F008869B1 /* ObjectMapper */, + ); productName = iSimulator; productReference = 292EADA01F458B3D009FC1ED /* iSimulator.app */; productType = "com.apple.product-type.application"; @@ -234,6 +221,9 @@ Base, ); mainGroup = 292EAD971F458B3D009FC1ED; + packageReferences = ( + 8CA3047C2AE34B8F008869B1 /* XCRemoteSwiftPackageReference "ObjectMapper" */, + ); productRefGroup = 292EADA11F458B3D009FC1ED /* Products */; projectDirPath = ""; projectRoot = ""; @@ -406,7 +396,8 @@ MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; }; name = Release; }; @@ -425,7 +416,10 @@ "$(PROJECT_DIR)/Carthage/Build/Mac", ); INFOPLIST_FILE = iSimulator/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.15; MARKETING_VERSION = 3.3.0; OTHER_CODE_SIGN_FLAGS = ""; @@ -451,7 +445,10 @@ "$(PROJECT_DIR)/Carthage/Build/Mac", ); INFOPLIST_FILE = iSimulator/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.15; MARKETING_VERSION = 3.3.0; OTHER_CODE_SIGN_FLAGS = ""; @@ -485,6 +482,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 8CA3047C2AE34B8F008869B1 /* XCRemoteSwiftPackageReference "ObjectMapper" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Hearst-DD/ObjectMapper"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 4.2.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 8CA3047D2AE34B8F008869B1 /* ObjectMapper */ = { + isa = XCSwiftPackageProductDependency; + package = 8CA3047C2AE34B8F008869B1 /* XCRemoteSwiftPackageReference "ObjectMapper" */; + productName = ObjectMapper; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 292EAD981F458B3D009FC1ED /* Project object */; } From a28a97b81836975b995ef6aa27ece55ada8ce474 Mon Sep 17 00:00:00 2001 From: Ricardo Nunez Date: Fri, 20 Oct 2023 17:05:49 -0700 Subject: [PATCH 2/3] Removes some unused files --- iSimulator.xcodeproj/project.pbxproj | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/iSimulator.xcodeproj/project.pbxproj b/iSimulator.xcodeproj/project.pbxproj index 0aaeaf4..1484b39 100644 --- a/iSimulator.xcodeproj/project.pbxproj +++ b/iSimulator.xcodeproj/project.pbxproj @@ -31,8 +31,6 @@ 31CD6D0221B2817900E49DC0 /* RootLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31CD6D0121B2817900E49DC0 /* RootLink.swift */; }; 31CD6D0421B2942300E49DC0 /* ApplicationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31CD6D0321B2942300E49DC0 /* ApplicationCache.swift */; }; 8CA3047E2AE34B8F008869B1 /* ObjectMapper in Frameworks */ = {isa = PBXBuildFile; productRef = 8CA3047D2AE34B8F008869B1 /* ObjectMapper */; }; - CFDB43E0264BCE6E0075BDDC /* Cartfile in Resources */ = {isa = PBXBuildFile; fileRef = CFDB43DF264BCE6E0075BDDC /* Cartfile */; }; - CFDB43E4264BD5E50075BDDC /* Cartfile.resolved in Resources */ = {isa = PBXBuildFile; fileRef = CFDB43E3264BD5E50075BDDC /* Cartfile.resolved */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -62,8 +60,6 @@ 3198338821A7F5FE004ADEE3 /* ObjectMapper.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ObjectMapper.framework; path = Carthage/Build/Mac/ObjectMapper.framework; sourceTree = ""; }; 31CD6D0121B2817900E49DC0 /* RootLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootLink.swift; sourceTree = ""; }; 31CD6D0321B2942300E49DC0 /* ApplicationCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationCache.swift; sourceTree = ""; }; - CFDB43DF264BCE6E0075BDDC /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cartfile; sourceTree = SOURCE_ROOT; }; - CFDB43E3264BD5E50075BDDC /* Cartfile.resolved */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile.resolved; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -125,7 +121,6 @@ 292EADA21F458B3D009FC1ED /* iSimulator */ = { isa = PBXGroup; children = ( - CFDB43DE264BCE5D0075BDDC /* Support */, 29157C581F4D62940069BDB6 /* Models */, 29157C531F4D56310069BDB6 /* Tools */, 292EADB21F458C89009FC1ED /* UI */, @@ -159,15 +154,6 @@ name = Frameworks; sourceTree = ""; }; - CFDB43DE264BCE5D0075BDDC /* Support */ = { - isa = PBXGroup; - children = ( - CFDB43DF264BCE6E0075BDDC /* Cartfile */, - CFDB43E3264BD5E50075BDDC /* Cartfile.resolved */, - ); - name = Support; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -238,9 +224,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - CFDB43E0264BCE6E0075BDDC /* Cartfile in Resources */, 292EADA81F458B3D009FC1ED /* Assets.xcassets in Resources */, - CFDB43E4264BD5E50075BDDC /* Cartfile.resolved in Resources */, 292EADAB1F458B3D009FC1ED /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; From 5fc388e43e9263e95140f1eaca1f1c953c74f4fd Mon Sep 17 00:00:00 2001 From: Ricardo Nunez Date: Fri, 20 Oct 2023 18:21:50 -0700 Subject: [PATCH 3/3] Uses Decodable instead of `ObjectMapper` --- iSimulator.xcodeproj/project.pbxproj | 38 ++-------------- iSimulator/Models/Device.swift | 23 ++++++---- iSimulator/Models/DeviceType.swift | 19 ++++---- iSimulator/Models/Pair.swift | 24 +++++----- iSimulator/Models/Runtime.swift | 68 ++++++++++++++++++---------- iSimulator/Models/TotalModel.swift | 37 +++++++++------ 6 files changed, 107 insertions(+), 102 deletions(-) diff --git a/iSimulator.xcodeproj/project.pbxproj b/iSimulator.xcodeproj/project.pbxproj index 1484b39..178dc50 100644 --- a/iSimulator.xcodeproj/project.pbxproj +++ b/iSimulator.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -30,7 +30,6 @@ 315A809D22C90616005C2493 /* AppGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 315A809C22C90616005C2493 /* AppGroup.swift */; }; 31CD6D0221B2817900E49DC0 /* RootLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31CD6D0121B2817900E49DC0 /* RootLink.swift */; }; 31CD6D0421B2942300E49DC0 /* ApplicationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31CD6D0321B2942300E49DC0 /* ApplicationCache.swift */; }; - 8CA3047E2AE34B8F008869B1 /* ObjectMapper in Frameworks */ = {isa = PBXBuildFile; productRef = 8CA3047D2AE34B8F008869B1 /* ObjectMapper */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -67,7 +66,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8CA3047E2AE34B8F008869B1 /* ObjectMapper in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -171,7 +169,6 @@ ); name = iSimulator; packageProductDependencies = ( - 8CA3047D2AE34B8F008869B1 /* ObjectMapper */, ); productName = iSimulator; productReference = 292EADA01F458B3D009FC1ED /* iSimulator.app */; @@ -208,7 +205,6 @@ ); mainGroup = 292EAD971F458B3D009FC1ED; packageReferences = ( - 8CA3047C2AE34B8F008869B1 /* XCRemoteSwiftPackageReference "ObjectMapper" */, ); productRefGroup = 292EADA11F458B3D009FC1ED /* Products */; projectDirPath = ""; @@ -380,8 +376,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; }; name = Release; }; @@ -400,10 +395,7 @@ "$(PROJECT_DIR)/Carthage/Build/Mac", ); INFOPLIST_FILE = iSimulator/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.15; MARKETING_VERSION = 3.3.0; OTHER_CODE_SIGN_FLAGS = ""; @@ -429,10 +421,7 @@ "$(PROJECT_DIR)/Carthage/Build/Mac", ); INFOPLIST_FILE = iSimulator/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.15; MARKETING_VERSION = 3.3.0; OTHER_CODE_SIGN_FLAGS = ""; @@ -466,25 +455,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8CA3047C2AE34B8F008869B1 /* XCRemoteSwiftPackageReference "ObjectMapper" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/Hearst-DD/ObjectMapper"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 4.2.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8CA3047D2AE34B8F008869B1 /* ObjectMapper */ = { - isa = XCSwiftPackageProductDependency; - package = 8CA3047C2AE34B8F008869B1 /* XCRemoteSwiftPackageReference "ObjectMapper" */; - productName = ObjectMapper; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = 292EAD981F458B3D009FC1ED /* Project object */; } diff --git a/iSimulator/Models/Device.swift b/iSimulator/Models/Device.swift index 4b25b10..6d5216a 100644 --- a/iSimulator/Models/Device.swift +++ b/iSimulator/Models/Device.swift @@ -7,10 +7,9 @@ // import Foundation -import ObjectMapper -class Device: Mappable { - enum State: String { +final class Device: Decodable { + enum State: String, Decodable { case booted = "Booted" case shutdown = "Shutdown" } @@ -47,15 +46,19 @@ class Device: Mappable { } - required init?(map: Map) { - + enum CodingKeys: CodingKey { + case state + case availability + case name + case udid } - func mapping(map: Map) { - state <- (map["state"], EnumTransform()) - availability <- (map["availability"], EnumTransform()) - name <- map["name"] - udid <- map["udid"] + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + state = try container.decode(Device.State.self, forKey: .state) + availability = try container.decodeIfPresent(Availability.self, forKey: .availability) ?? .unavailable + name = try container.decode(String.self, forKey: .name) + udid = try container.decode(String.self, forKey: .udid) } var dataReportDic: [String: String] { diff --git a/iSimulator/Models/DeviceType.swift b/iSimulator/Models/DeviceType.swift index fe9c4b1..2dd0192 100644 --- a/iSimulator/Models/DeviceType.swift +++ b/iSimulator/Models/DeviceType.swift @@ -7,17 +7,20 @@ // import Foundation -import ObjectMapper -class DeviceType: Mappable { - var name = "" - var identifier = "" +struct DeviceType: Decodable { + let name: String + let identifier: String - required init?(map: Map) { } + enum CodingKeys: CodingKey { + case name + case identifier + } - func mapping(map: Map) { - name <- map["name"] - identifier <- map["identifier"] + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + name = try container.decode(String.self, forKey: .name) + identifier = try container.decode(String.self, forKey: .identifier) } var dataReportDic: [String: String] { diff --git a/iSimulator/Models/Pair.swift b/iSimulator/Models/Pair.swift index e981cf5..ae077f1 100644 --- a/iSimulator/Models/Pair.swift +++ b/iSimulator/Models/Pair.swift @@ -7,22 +7,24 @@ // import Foundation -import ObjectMapper -class Pair: Mappable { +struct Pair: Decodable { - var watch: Device? - var phone: Device? - var state = "" + let watch: Device? + let phone: Device? + let state: String - required init?(map: Map) { - + enum CodingKeys: CodingKey { + case watch + case phone + case state } - func mapping(map: Map) { - watch <- map["watch"] - phone <- map["phone"] - state <- map["state"] + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + watch = try container.decodeIfPresent(Device.self, forKey: .watch) + phone = try container.decodeIfPresent(Device.self, forKey: .phone) + state = try container.decode(String.self, forKey: .state) } var dataReportDic: [String: String] { diff --git a/iSimulator/Models/Runtime.swift b/iSimulator/Models/Runtime.swift index 080b059..f9a3ae8 100644 --- a/iSimulator/Models/Runtime.swift +++ b/iSimulator/Models/Runtime.swift @@ -7,48 +7,68 @@ // import Foundation -import ObjectMapper -enum Availability: String { - case available = "(available)" - case unavailable = "(unavailable, runtime profile not found)" +enum Availability: Decodable { + case available, unavailable + + init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + let rawValue = try container.decode(String.self) + + switch rawValue { + case "(available)": + self = .available + case "(unavailable, runtime profile not found)", "(unavailable)": + self = .unavailable + default: + throw DecodingError.valueNotFound(String.self, .init(codingPath: decoder.codingPath, debugDescription: "Unknown Availability type \(rawValue)")) + } + } } -class Runtime: Mappable { +final class Runtime: Decodable { enum OSType: String { case iOS, tvOS, watchOS, None } - var buildversion = "" - var availability = Availability.unavailable - var name = "" - var identifier = "" - var version = "" - var devices: [Device] = [] - var devicetypes: [DeviceType] = [] + let buildversion: String + let availability: Availability + let name: String + let identifier: String + let version: String + var devices: [Device] + var devicetypes: [DeviceType] + var osType: OSType{ - if name.contains("iOS"){ + if name.contains("iOS") { return .iOS - }else if name.contains("tvOS"){ + } else if name.contains("tvOS") { return .tvOS - }else if name.contains("watchOS"){ + } else if name.contains("watchOS") { return .watchOS - }else{ + } else{ return .None } } - required init?(map: Map) { - + enum CodingKeys: CodingKey { + case buildversion + case availability + case name + case identifier + case version } - func mapping(map: Map) { - buildversion <- map["buildversion"] - availability <- (map["availability"], EnumTransform()) - name <- map["name"] - identifier <- map["identifier"] - version <- map["version"] + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + buildversion = try container.decode(String.self, forKey: .buildversion) + availability = try container.decodeIfPresent(Availability.self, forKey: .availability) ?? .unavailable + name = try container.decode(String.self, forKey: .name) + identifier = try container.decode(String.self, forKey: .identifier) + version = try container.decode(String.self, forKey: .version) + devices = [] + devicetypes = [] } var dataReportDic: [String: String] { diff --git a/iSimulator/Models/TotalModel.swift b/iSimulator/Models/TotalModel.swift index 0c6dbe0..93e5837 100644 --- a/iSimulator/Models/TotalModel.swift +++ b/iSimulator/Models/TotalModel.swift @@ -7,11 +7,10 @@ // import AppKit -import ObjectMapper -class TotalModel: Mappable { +final class TotalModel: Decodable { - static let `default` = TotalModel() + static var `default` = TotalModel() var isForceUpdate = true private var lastXcodePath = "" @@ -55,7 +54,14 @@ class TotalModel: Mappable { } } let jsonStr = shell("/usr/bin/xcrun", arguments: "simctl", "list", "-j").outStr - _ = Mapper().map(JSONString: jsonStr, toObject: TotalModel.default) + + if let jsonData = jsonStr.data(using: .utf8) { + do { + TotalModel.default = try JSONDecoder().decode(TotalModel.self, from: jsonData) + } catch { + print("Error decoding TotalModel: \(error)") + } + } } var runtimes: [Runtime] = [] @@ -83,19 +89,20 @@ class TotalModel: Mappable { } - required init?(map: Map) { - + enum CodingKeys: CodingKey { + case runtimes + case devicetypes + case devices + case pairs } - func mapping(map: Map) { - runtimes.removeAll() - devicetypes.removeAll() - devices.removeAll() - pairs.removeAll() - runtimes <- map["runtimes"] - devicetypes <- map["devicetypes"] - devices <- map["devices"] - pairs <- map["pairs"] + required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + runtimes = try container.decode([Runtime].self, forKey: .runtimes) + devicetypes = try container.decode([DeviceType].self, forKey: .devicetypes) + devices = try container.decode([String: [Device]].self, forKey: .devices) + pairs = try container.decode([String: Pair].self, forKey: .pairs) + // 关联 runtime 和 device/devicetype runtimes.forEach{ r in r.devices = self.devices[r.name] ?? (self.devices[r.identifier] ?? [])