OSDN Git Service

SwiftyJSONを導入
authormasakih <masakih@users.sourceforge.jp>
Sun, 19 Mar 2017 03:03:21 +0000 (12:03 +0900)
committermasakih <masakih@users.sourceforge.jp>
Sun, 19 Mar 2017 03:03:21 +0000 (12:03 +0900)
Carthageを利用

32 files changed:
.gitignore
Cartfile [new file with mode: 0644]
Cartfile.resolved [new file with mode: 0644]
KCD.xcodeproj/project.pbxproj
KCD/APIResponse.swift
KCD/AirBaseMapper.swift
KCD/AirCorpsSupplyCommand.swift
KCD/ApplySuppliesCommand.swift
KCD/BasicMapper.swift
KCD/CalculateDamageCommand.swift
KCD/CombinedCommand.swift
KCD/DestroyItem2Command.swift
KCD/DropShipHistoryCommand.swift
KCD/DummyShipCommand.swift
KCD/GuardShelterCommand.swift
KCD/JSONCommand.swift
KCD/JSONMapper.swift
KCD/JSONNode.swift
KCD/JSONViewCommand.swift
KCD/KaisouLockCommand.swift
KCD/MapStartCommand.swift
KCD/MasterShipMapper.swift
KCD/MaterialMapper.swift
KCD/QuestListCommand.swift
KCD/RemodelSlotItemCommand.swift
KCD/SetPlaneCommand.swift
KCD/ShipMapper.swift
KCD/SlotItemMapper.swift
KCD/SlotResetCommand.swift
KCD/StoreCreateSlotItemHistoryCommand.swift
KCD/UpdateSlotItemCommand.swift
Makefile

index 12c5bf0..f987f7d 100644 (file)
@@ -5,3 +5,7 @@ xcdebugger
 xcuserdata
 /build/
 .DS_Store
+
+#Carthage
+Carthage/Build
+
diff --git a/Cartfile b/Cartfile
new file mode 100644 (file)
index 0000000..b570baa
--- /dev/null
+++ b/Cartfile
@@ -0,0 +1,2 @@
+github "SwiftyJSON/SwiftyJSON"
+
diff --git a/Cartfile.resolved b/Cartfile.resolved
new file mode 100644 (file)
index 0000000..5f3c1a6
--- /dev/null
@@ -0,0 +1 @@
+github "SwiftyJSON/SwiftyJSON" "3.1.4"
index c1024e0..5aa1a7a 100644 (file)
                F4E5FF121E17D6850026868C /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E5FF111E17D6850026868C /* GameViewController.swift */; };
                F4E5FF141E17F93B0026868C /* BroserWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E5FF131E17F93B0026868C /* BroserWindowController.swift */; };
                F4E7802E18DC3AF00011BC4C /* LocalData.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F4E7802C18DC3AF00011BC4C /* LocalData.xcdatamodeld */; };
+               F4EFBCA31E7D439A00DE4A58 /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4EFBCA21E7D439A00DE4A58 /* SwiftyJSON.framework */; };
+               F4EFBCA51E7D757E00DE4A58 /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4EFBCA21E7D439A00DE4A58 /* SwiftyJSON.framework */; };
+               F4EFBCA61E7D757E00DE4A58 /* SwiftyJSON.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F4EFBCA21E7D439A00DE4A58 /* SwiftyJSON.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
                F4F947071D5DBA2D00F95998 /* MapWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4F947091D5DBA2D00F95998 /* MapWindowController.xib */; };
                F4F9470A1D5DBA3800F95998 /* EquipmentWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4F9470C1D5DBA3800F95998 /* EquipmentWindowController.xib */; };
                F4F9471F1D5DBBC700F95998 /* RepairListViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4F947211D5DBBC700F95998 /* RepairListViewController.xib */; };
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                };
+               F4EFBCA71E7D757E00DE4A58 /* Embed Frameworks */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = "";
+                       dstSubfolderSpec = 10;
+                       files = (
+                               F4EFBCA61E7D757E00DE4A58 /* SwiftyJSON.framework in Embed Frameworks */,
+                       );
+                       name = "Embed Frameworks";
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
                F4E5FF111E17D6850026868C /* GameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = "<group>"; };
                F4E5FF131E17F93B0026868C /* BroserWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BroserWindowController.swift; sourceTree = "<group>"; };
                F4E7802D18DC3AF00011BC4C /* LocalData.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = LocalData.xcdatamodel; sourceTree = "<group>"; };
+               F4EFBCA21E7D439A00DE4A58 /* SwiftyJSON.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyJSON.framework; path = Carthage/Build/Mac/SwiftyJSON.framework; sourceTree = "<group>"; };
                F4F947061D5DBA1A00F95998 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UITestWindowController.xib; sourceTree = "<group>"; };
                F4F947081D5DBA2D00F95998 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MapWindowController.xib; sourceTree = "<group>"; };
                F4F9470B1D5DBA3800F95998 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/EquipmentWindowController.xib; sourceTree = "<group>"; };
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               F4EFBCA51E7D757E00DE4A58 /* SwiftyJSON.framework in Frameworks */,
+                               F4EFBCA31E7D439A00DE4A58 /* SwiftyJSON.framework in Frameworks */,
                                F4A2AF581A0930160024BD9E /* Quartz.framework in Frameworks */,
                                F4B3DC4E18F0C8FF0011B4FC /* Accounts.framework in Frameworks */,
                                F4B3DC4C18F0C8A90011B4FC /* Social.framework in Frameworks */,
                F4BDEB45187252F30069D0CE /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
+                               F4EFBCA21E7D439A00DE4A58 /* SwiftyJSON.framework */,
                                F4A2AF571A0930160024BD9E /* Quartz.framework */,
                                F4B3DC4D18F0C8FF0011B4FC /* Accounts.framework */,
                                F4B3DC4B18F0C8A90011B4FC /* Social.framework */,
                                F4BDEB40187252F30069D0CE /* Frameworks */,
                                F4BDEB41187252F30069D0CE /* Resources */,
                                F4EA96E71E75464A00515C6C /* ShellScript */,
+                               F4EFBCA71E7D757E00DE4A58 /* Embed Frameworks */,
                        );
                        buildRules = (
                        );
                                ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
                                CLANG_ENABLE_MODULES = YES;
                                COMBINE_HIDPI_IMAGES = YES;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)/Carthage/Build/Mac",
+                               );
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "$(inherited)",
                                        "ENABLE_JSON_LOG=1",
                                ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
                                CLANG_ENABLE_MODULES = YES;
                                COMBINE_HIDPI_IMAGES = YES;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "$(PROJECT_DIR)/Carthage/Build/Mac",
+                               );
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "COREDATA_STORE_TYPE=0",
                                        "UI_TEST=0",
index 9bfcdf6..bc437b9 100644 (file)
@@ -7,6 +7,18 @@
 //
 
 import Cocoa
+import SwiftyJSON
+
+extension JSON {
+    func value(for keyPath: String) -> JSON {
+        return self[keyPath.components(separatedBy: ".")]
+    }
+    
+    var last: JSON {
+        let index = self.count - 1
+        return self[index]
+    }
+}
 
 fileprivate extension Data {
     var utf8String: String? { return String(data: self, encoding: .utf8) }
@@ -19,7 +31,7 @@ fileprivate extension Dictionary {
     }
 }
 
-fileprivate func splitJSON(_ data: Data) -> Data? {
+fileprivate func splitJSON(_ data: Data) -> String? {
     let prefix = "svdata="
     guard let string = data.utf8String,
         let range = string.range(of: prefix)
@@ -27,14 +39,7 @@ fileprivate func splitJSON(_ data: Data) -> Data? {
             print("data is wrong")
             return nil
     }
-    return string[range.upperBound..<string.endIndex].data(using: .utf8)
-}
-fileprivate func parseJSON(_ data: Data?) -> [String: Any]? {
-    guard let data = data,
-        let j = try? JSONSerialization.jsonObject(with: data, options: [.allowFragments]),
-        let json = j as? [String: Any]
-        else { return nil }
-    return json
+    return string[range.upperBound..<string.endIndex]
 }
 
 fileprivate func parseParameter(_ request: URLRequest) -> [String: String]? {
@@ -52,22 +57,22 @@ fileprivate func parseParameter(_ request: URLRequest) -> [String: String]? {
 struct APIResponse {
     let api: String
     let parameter: [String: String]
-    let json: [String: Any]
+    let json: JSON
     let date: Date
     var success: Bool {
-        if let r = json["api_result"] as? Int { return r == 1 }
+        if let r = json["api_result"].int { return r == 1 }
         return false
     }
     
     init?(request: URLRequest, data: Data) {
         date = Date()
         
-        guard let json = parseJSON(splitJSON(data))
+        guard let josn = splitJSON(data)
             else {
                 print("Can not parse JSON")
                 return nil
         }
-        self.json = json
+        self.json = JSON(parseJSON: josn)
         
         guard let parameter = parseParameter(request)
             else {
index 3729b9f..02e1d5f 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 class AirBaseMapper: JSONMapper {
     typealias ObjectType = AirBase
@@ -21,7 +22,7 @@ class AirBaseMapper: JSONMapper {
         self.apiResponse = apiResponse
     }
 
-    func handleExtraValue(_ value: Any, forKey key: String, to airbase: AirBase) -> Bool {
+    func handleExtraValue(_ value: JSON, forKey key: String, to airbase: AirBase) -> Bool {
         if key != "api_plane_info" { return false }
         
         if airbase.planeInfo.count == 0 {
@@ -33,7 +34,7 @@ class AirBaseMapper: JSONMapper {
             }
         }
         
-        guard let planeInfos = value as? [[String: Any]]
+        guard let planeInfos = value.array
             else {
                 print("value is wrong")
                 return false
@@ -44,14 +45,14 @@ class AirBaseMapper: JSONMapper {
                 return false
         }
         zip(infos, planeInfos).forEach { (info, dict) in
-            guard let slotid = dict["api_slotid"] as? Int,
+            guard let slotid = dict["api_slotid"].int,
                 slotid != 0
                 else { return }
-            guard let cond = dict["api_cond"] as? Int,
-                let count = dict["api_count"] as? Int,
-                let maxCount = dict["api_max_count"] as? Int,
-                let squadronid = dict["api_squadron_id"] as? Int,
-                let state = dict["api_state"] as? Int
+            guard let cond = dict["api_cond"].int,
+                let count = dict["api_count"].int,
+                let maxCount = dict["api_max_count"].int,
+                let squadronid = dict["api_squadron_id"].int,
+                let state = dict["api_state"].int
                 else { return print("planeInfos is wrong") }
             info.cond = cond
             info.count = count
index b2abcbc..180e58b 100644 (file)
@@ -19,11 +19,9 @@ class AirCorpsSupplyCommand: JSONCommand {
         guard let areaId = arguments["api_area_id"].flatMap({ Int($0) }),
             let rId = arguments["api_base_id"].flatMap({ Int($0) }),
             let squadronIdsString = arguments["api_squadron_id"],
-            let data = json[dataKey] as? [String: Any],
-            let planeInfos = data["api_plane_info"] as? [[String: Any]],
-            planeInfos.count != 0,
             let airBase = store.airBase(area: areaId, base: rId)
             else { return }
+        let planeInfos = data["api_plane_info"]
         let planes = airBase.planeInfo
         let squadronIds = squadronIdsString
             .components(separatedBy: ",")
@@ -35,17 +33,17 @@ class AirCorpsSupplyCommand: JSONCommand {
                 else { return }
             let planeInfo = planeInfos[$0.offset]
             
-            if let v = planeInfo["api_cond"] as? Int { plane.cond = v }
-            if let v = planeInfo["api_slotid"] as? Int { plane.slotid = v }
-            if let v = planeInfo["api_state"] as? Int { plane.state = v }
-            if let v = planeInfo["api_count"] as? Int { plane.count = v }
-            if let v = planeInfo["api_max_count"] as? Int { plane.max_count = v }
+            if let v = planeInfo["api_cond"].int { plane.cond = v }
+            if let v = planeInfo["api_slotid"].int { plane.slotid = v }
+            if let v = planeInfo["api_state"].int { plane.state = v }
+            if let v = planeInfo["api_count"].int { plane.count = v }
+            if let v = planeInfo["api_max_count"].int { plane.max_count = v }
         }
-        if let v = data["api_distance"] as? Int { airBase.distance = v }
+        if let v = data["api_distance"].int { airBase.distance = v }
         
         guard let material = store.material()
             else { return }
-        if let v = data["api_after_bauxite"] as? Int { material.bauxite = v }
-        if let v = data["api_after_fuel"] as? Int { material.fuel = v }
+        if let v = data["api_after_bauxite"].int { material.bauxite = v }
+        if let v = data["api_after_fuel"].int { material.fuel = v }
     }
 }
index 448aa94..fce3dbd 100644 (file)
@@ -11,24 +11,22 @@ import Cocoa
 class ApplySuppliesCommand: JSONCommand {
     override func execute() {
         let store = ServerDataStore.oneTimeEditor()
-        guard let data = json["api_data"] as? [String: Any],
-            let infos = data["api_ship"] as? [[String: Any]]
-            else { return }
-        infos.forEach {
-            guard let i = $0["api_id"] as? Int,
-                let ship = store.ship(byId: i),
-                let bull = $0["api_bull"] as? Int,
-                let fuel = $0["api_fuel"] as? Int,
-                let slots = $0["api_onslot"] as? [Int],
-                slots.count > 4
-                else { return }
-            ship.bull = bull
-            ship.fuel = fuel
-            ship.onslot_0 = slots[0]
-            ship.onslot_1 = slots[1]
-            ship.onslot_2 = slots[2]
-            ship.onslot_3 = slots[3]
-            ship.onslot_4 = slots[4]
+        data["api_ship"]
+            .forEach { (_, json) in
+                guard let i = json["api_id"].int,
+                    let ship = store.ship(byId: i),
+                    let bull = json["api_bull"].int,
+                    let fuel = json["api_fuel"].int,
+                    let slots = json["api_onslot"].arrayObject as? [Int],
+                    slots.count > 4
+                    else { return }
+                ship.bull = bull
+                ship.fuel = fuel
+                ship.onslot_0 = slots[0]
+                ship.onslot_1 = slots[1]
+                ship.onslot_2 = slots[2]
+                ship.onslot_3 = slots[3]
+                ship.onslot_4 = slots[4]
         }
     }
 }
index 90b4441..199746a 100644 (file)
@@ -36,10 +36,6 @@ class BasicMapper: JSONMapper {
     }
     
     func commit() {
-        let j = apiResponse.json as NSDictionary
-        guard let data = j.value(forKeyPath: configuration.dataKey) as? [String: Any]
-            else { return print("json is wrong") }
-        
         let store = ServerDataStore.oneTimeEditor()
         guard let basic = store.basic() ?? store.createBasic()
             else { return print("Can not Get Basic") }
index 51009ab..1b9a4c9 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 fileprivate enum BattleType {
     case normal
@@ -146,6 +147,25 @@ class CalculateDamageCommand: JSONCommand {
 }
 // MARK: - Primitive Calclator
 extension CalculateDamageCommand {
+    
+    private func hogekiTargets(_ list: JSON) -> [[Int]]? {
+        guard let targetArraysArray = list
+            .array?
+            .flatMap({ $0.array?.flatMap { $0.int } }),
+            list.count - 1 == targetArraysArray.count
+            else { return nil }
+        return targetArraysArray
+    }
+    private func hogekiDamages(_ list: JSON) -> [[Int]]? {
+        guard let hougeki1Damages = list
+            .array?
+            .flatMap({ $0.array?.flatMap { $0.int } })
+            else { return nil }
+        return hougeki1Damages
+    }
+    private func enemyFlags(_ list: JSON) -> [Int]? {
+        return list.array?.flatMap { $0.int }.filter { $0 != -1 }
+    }
     private func isTargetFriend(eFlags: [Int]?, index: Int) -> Bool {
         if let eFlags = eFlags, 0..<eFlags.count ~= index {
             return eFlags[index] == 1
@@ -156,18 +176,12 @@ extension CalculateDamageCommand {
         calculateHogeki(baseKeyPath: baseKeyPath, battleFleet: bf())
     }
     fileprivate func calculateHogeki(baseKeyPath: String, battleFleet: BattleFleet = .first) {
-        let j = json as NSDictionary
-        guard let data = j.value(forKeyPath: baseKeyPath) as? [String: Any],
-            let dfList = data["api_df_list"] as? [Any],
-            let damageList = data["api_damage"] as? [Any]
-            else { return }
-        guard let targetArraysArray = dfList.filter({ $0 is [Int] }) as? [[Int]],
-            dfList.count - 1 == targetArraysArray.count
+        guard let targetArraysArray = hogekiTargets(data["api_df_list"])
             else { return print("api_df_list is wrong") }
-        guard let hougeki1Damages = damageList.filter({ $0 is [Int] }) as? [[Int]],
+        guard let hougeki1Damages = hogekiDamages(data["api_damage"]),
             targetArraysArray.count == hougeki1Damages.count
             else { return print("api_damage is wrong") }
-        let eFlags: [Int]? = (data["api_at_eflag"] as? [Int])?.filter { $0 != -1 }
+        let eFlags: [Int]? = enemyFlags(data["api_at_eflag"])
         
         Debug.print("Start Hougeki \(baseKeyPath)", level: .debug)
         let shipOffset = (battleFleet == .second) ? 6 : 0
@@ -210,9 +224,9 @@ extension CalculateDamageCommand {
         calculateFDam(baseKeyPath: baseKeyPath, battleFleet: bf())
     }
     fileprivate func calculateFDam(baseKeyPath: String, battleFleet: BattleFleet = .first) {
-        let j = json as NSDictionary
-        guard let data = j.value(forKeyPath: baseKeyPath) as? [String: Any],
-            let koukuDamages = data["api_fdam"] as? [Int]
+        guard let koukuDamages = json
+            .value(for: baseKeyPath)["api_fdam"]
+            .arrayObject as? [Int]
             else { return }
         
         Debug.print("Start FDam \(baseKeyPath)", level: .debug)
index c2033b7..4a11a6f 100644 (file)
@@ -28,9 +28,7 @@ class CombinedCommand: JSONCommand {
     
     override func execute() {
         if api == "/kcsapi/api_port/port" {
-            guard let data = json["api_data"] as? [String: Any]
-                else { return }
-            if let t = data["api_combined_flag"] as? Int {
+            if let t = data["api_combined_flag"].int {
                 CombineType(rawValue: t)
                     .map { postNotification(withType: $0) }
             } else {
index a9f006b..842c7e5 100644 (file)
@@ -25,8 +25,7 @@ class DestroyItem2Command: JSONCommand {
         
         guard let material = store.material()
             else { return print("Material is not found") }
-        guard let data = json[dataKey] as? [String: Any],
-            let gm = data["api_get_material"] as? [Int]
+        guard let gm = data["api_get_material"].arrayObject as? [Int]
             else { return print("api_get_material is wrong") }
         let resouces = ["fuel", "bull", "steel", "bauxite"]
         zip(gm, resouces).forEach {
index 8a27c62..15d230e 100644 (file)
@@ -15,10 +15,8 @@ class DropShipHistoryCommand: JSONCommand {
         }
         if !api.hasSuffix("battleresult") { return }
         
-        guard let data = json[dataKey] as? [String: Any],
-            let getShip = data["api_get_ship"] as? [String: Any],
-            let shipName = getShip["api_ship_name"] as? String,
-            let winRank = data["api_win_rank"] as? String
+        guard let shipName = data["api_get_ship"]["api_ship_name"].string,
+            let winRank = data["api_win_rank"].string
             else { return }
         guard let battle = TemporaryDataStore.default.battle()
             else { return print("Can not get Battle") }
index ec0081a..3640b87 100644 (file)
@@ -21,8 +21,7 @@ class DummyShipCommand: JSONCommand {
     }
     
     private func checkGetShip() {
-        guard let data = json[dataKey] as? [String: Any],
-            let _ = data["api_get_ship"]
+        guard !data["api_get_ship"].exists()
             else { return }
         DummyShipCommand.needsEnterDummy = true
     }
index f67313a..d1ecba1 100644 (file)
@@ -65,17 +65,16 @@ class GuardShelterCommand: JSONCommand {
         return nil
     }
     private func registerReserve() {
-        guard let data = json[dataKey] as? [String: Any],
-            let escape = data["api_escape"] as? [String: Any],
-            let guardians = escape["api_tow_idx"] as? [Int],
-            let guardianPos = guardians.first
+        let escape = data["api_escape"]
+        let guardians = escape["api_tow_idx"]
+        guard let guardianPos = guardians[0].int
             else { return }
         let fixedGuardianPos = guardianPos - 6 - 1
         guard 0..<6 ~= fixedGuardianPos,
             let guardianId = fleetMembers(fleetId: 2)?[fixedGuardianPos]
             else { return print("guardianPos is wrong") }
         
-        guard let escapeIdx = escape["api_escape_idx"],
+        guard let escapeIdx = escape["api_escape_idx"].int,
             let damagedPos = damagedMemberPosition(escapeIdx: escapeIdx),
             let damagedId = damagedShipId(damagedPos: damagedPos)
             else { return print("damagedPos is wrong") }
index cf5238b..d6bd594 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 class JSONCommand {
     class func canExecuteAPI(_ api: String) -> Bool { return false }
@@ -19,9 +20,9 @@ class JSONCommand {
     
     var api: String { return apiResponse.api }
     var arguments: [String: String] { return apiResponse.parameter }
-    var json: [String: Any] { return apiResponse.json }
+    var json: JSON { return apiResponse.json }
     
-    var dataKey: String { return "api_data" }
+    var data: JSON { return json["api_data"] }
 
     func execute() throws {}
 }
index 1cf5c76..54055e4 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 struct MappingConfiguration<T: NSManagedObject> {
     let entity: Entity<T>
@@ -39,10 +40,10 @@ protocol JSONMapper {
     var apiResponse: APIResponse { get }
     var configuration: MappingConfiguration<ObjectType> { get }
     
-    func registerElement(_ element: [String: Any], to object: ObjectType)
+    func registerElement(_ element: JSON, to object: ObjectType)
     func commit()
     func beginRegister(_ object: ObjectType)
-    func handleExtraValue(_ value: Any, forKey key: String, to object: ObjectType) -> Bool
+    func handleExtraValue(_ value: JSON, forKey key: String, to object: ObjectType) -> Bool
     func finishOperating()
 }
 
@@ -55,13 +56,15 @@ extension String {
 }
 
 extension JSONMapper {
+    var data: JSON { return apiResponse.json.value(for: configuration.dataKey) }
+    
     private func isEqual(_ lhs: AnyObject?, _ rhs: AnyObject?) -> Bool {
         if lhs == nil, rhs == nil { return true }
         if let lhs = lhs, let rhs = rhs { return lhs.isEqual(rhs) }
         return false
     }
-    func setValueIfNeeded(_ value: AnyObject?, to object: ObjectType, forKey key: String) {
-        var validValue = value
+    func setValueIfNeeded(_ value: JSON, to object: ObjectType, forKey key: String) {
+        var validValue = value.object as AnyObject?
         do {
             try object.validateValue(&validValue, forKey: key)
         } catch {
@@ -76,24 +79,24 @@ extension JSONMapper {
         }
     }
     
-    func registerElement(_ element: [String: Any], to object: ObjectType) {
+    func registerElement(_ element: JSON, to object: ObjectType) {
         beginRegister(object)
-        element.forEach { (key: String, value: Any) in
+        element.forEach { (key: String, value: JSON) in
             if configuration.ignoreKeys.contains(key) { return }
             if handleExtraValue(value, forKey: key, to: object) { return }
-            switch value {
-            case let a as [AnyObject]:
-                a.enumerated().forEach {
+            switch value.type {
+            case .array:
+                value.array?.enumerated().forEach {
                     let newKey = "\(key)_\($0.offset)"
                     setValueIfNeeded($0.element, to: object, forKey: newKey)
                 }
-            case let d as [String: AnyObject]:
-                d.forEach { (subKey: String, subValue) in
+            case .dictionary:
+                value.forEach { (subKey: String, subValue) in
                     let newKey = "\(key)_D_\(subKey.keyByDeletingPrefix())"
                     setValueIfNeeded(subValue, to: object, forKey: newKey)
                 }
             default:
-                setValueIfNeeded(value as AnyObject?, to: object, forKey: key)
+                setValueIfNeeded(value, to: object, forKey: key)
             }
         }
     }
@@ -101,31 +104,26 @@ extension JSONMapper {
         let keys = configuration.compositPrimaryKeys ?? [configuration.primaryKey]
         return keys.map { NSSortDescriptor(key: $0, ascending: true) }
     }
-    private func objectSearch(_ objects: [ObjectType], _ element: [String: Any]) -> ObjectType? {
+    private func objectSearch(_ objects: [ObjectType], _ element: JSON) -> ObjectType? {
         let keys = configuration.compositPrimaryKeys ?? [configuration.primaryKey]
         let keyPiar = keys.map { (key: $0, apiKey: "api_\($0)") }
         return objects.binarySearch {
             for piar in keyPiar {
                 guard let v1 = $0.value(forKey: piar.key)
                     else { return .orderedAscending }
-                guard let v2 = element[piar.apiKey]
-                    else { return .orderedDescending }
+                if element[piar.apiKey].type == .null { return .orderedDescending }
+                let v2 = element[piar.apiKey].object
                 return (v1 as AnyObject).compare(v2)
             }
             return .orderedDescending
         }
     }
     func commit() {
-        guard var d = (apiResponse.json as AnyObject).value(forKeyPath: configuration.dataKey)
-            else { return print("JSON is wrong.") }
-        if let dd = d as? NSDictionary { d = [dd] }
-        guard let data = d as? [[String: Any]]
-            else { return print("JSON is wrong.") }
-        
         let store = configuration.editorStore
         guard let objects = try? store.objects(with: configuration.entity, sortDescriptors: sortDescriptors)
             else { return print("Can not get entity named \(configuration.entity.name)") }
-        data.forEach {
+        let list = (data.type == .array ? data.arrayValue : [data])
+        list.forEach {
             if let object = objectSearch(objects, $0) {
                 registerElement($0, to: object)
             } else if let new = store.insertNewObject(for: configuration.entity) {
@@ -138,9 +136,8 @@ extension JSONMapper {
         store.saveActionCore()
     }
     
-    func execute() {}
     func beginRegister(_ object: ObjectType) {}
-    func handleExtraValue(_ value: Any, forKey key: String, to object: ObjectType) -> Bool {
+    func handleExtraValue(_ value: JSON, forKey key: String, to object: ObjectType) -> Bool {
         return false
     }
     func finishOperating() {}
index 74c0c17..552531a 100644 (file)
@@ -7,69 +7,39 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 class JSONNode: NSObject, NSCoding, NSCopying {
-    class func nodeWithJSON(_ json: AnyObject?) -> JSONNode? {
-        if let j = json as? NSArray { return node(withArray: j) }
-        if let j = json as? NSDictionary { return node(withDictionary: j) }
+    class func nodeWithJSON(_ json: JSON) -> JSONNode? {
+        if json.type == .array { return node(withArray: json) }
+        if json.type == .dictionary { return node(withDictionary: json) }
         return node(withObject: json)
     }
-    private class func node(withObject obj: AnyObject?) -> JSONNode? {
-        guard let obj = obj else { return nil }
+    private class func node(withObject obj: JSON) -> JSONNode? {
         let node = JSONLeafNode()
         let value: String?
-        switch obj {
-        case let v as String: value = v
-        case let v as Int: value = String(v)
-        case _ as NSNull: value = nil
+        switch obj.type {
+        case .string: value = obj.stringValue
+        case .number: value = String(obj.intValue)
+        case .null: value = nil
         default: print(obj); return nil
         }
         node.value = value
         return node
     }
-    private class func node(withArray array: NSArray) -> JSONNode {
+    private class func node(withArray array: JSON) -> JSONNode {
         let node = JSONContainerNode()
-        node.children = array.map {
-            if let node = JSONNode.nodeWithJSON($0 as AnyObject?) { return node }
-            
-            
-            // TODO: check enter below
-            print("Enter JSONNode ARRAY optional statment")
-            let node = JSONLeafNode()
-            let value: String?
-            switch $0 {
-            case let v as String: value = v
-            case let v as Int: value = String(v)
-            case _ as NSNull: value = nil
-            default: print($0); fatalError()
-            }
-            node.value = value
-            return node
-        }
+        node.children = array.flatMap { (_, json) in JSONNode.nodeWithJSON(json) }
         return node
     }
-    private class func node(withDictionary dict: NSDictionary) -> JSONNode {
-        guard let dict = dict as? [String: AnyObject] else { fatalError("JSON is broken.") }
+    private class func node(withDictionary dict: JSON) -> JSONNode {
         let node = JSONContainerNode()
-        node.children = dict.map { (d: (key: String, value: AnyObject)) -> JSONNode in
-            if let node = JSONNode.nodeWithJSON(d.value) {
-                node.key = d.key
+        node.children = dict.flatMap { (key: String, json: JSON) -> JSONNode? in
+            if let node = JSONNode.nodeWithJSON(json) {
+                node.key = key
                 return node
             }
-            
-            // TODO: check enter below
-            print("Enter JSONNode DICTIONAY optional statment")
-            let node = JSONLeafNode()
-            node.key = d.key
-            let value: String?
-            switch d.value {
-            case let v as String: value = v
-            case let v as Int: value = String(v)
-            case _ as NSNull: value = nil
-            default: print(d.value); fatalError()
-            }
-            node.value = value
-            return node
+            return nil
         }
         return node
     }
index b774545..527875d 100644 (file)
@@ -22,7 +22,7 @@ class JSONViewCommand: JSONCommand {
             .parameter
             .map { ["key": $0.0, "value": $0.1] }
         self.jsonTree = JSONNode
-            .nodeWithJSON(apiResponse.json as AnyObject?)
+            .nodeWithJSON(apiResponse.json)
             .map { [$0] }
         self.command = command
         super.init(apiResponse: apiResponse)
index e800296..39ad70e 100644 (file)
@@ -17,8 +17,7 @@ class KaisouLockCommand: JSONCommand {
     override func execute() {
         guard let slotId = arguments["api_slotitem_id"].flatMap({ Int($0) })
             else { return print("api_slotitem_id is wrong") }
-        guard let dic = json[dataKey] as? [String: Any],
-            let locked = dic["api_locked"] as? Bool
+        guard let locked = data["api_locked"].bool
             else { return print("api_locked is wrong") }
         let store = ServerDataStore.oneTimeEditor()
         store.slotItem(byId: slotId)?.locked = locked
index 02e9525..68a9b57 100644 (file)
@@ -40,8 +40,7 @@ class MapStartCommand: JSONCommand {
             let mapInfo = arguments["api_mapinfo_no"].flatMap({ Int($0) })
             else { return print("startBattle Arguments is wrong") }
         
-        guard let data = json["api_data"] as? [String: Any],
-            let no = data["api_no"] as? Int
+        guard let no = data["api_no"].int
             else { return print("startBattle JSON is wrong") }
         guard let battle = store.createBattle()
             else { return print("Can not create Battle") }
@@ -51,9 +50,8 @@ class MapStartCommand: JSONCommand {
         battle.no = no
     }
     private func nextCell() {
-        guard let data = json[dataKey] as? [String: Any],
-            let cellNumber = data["api_no"] as? Int,
-            let eventId = data["api_event_id"] as? Int
+        guard let cellNumber = data["api_no"].int,
+            let eventId = data["api_event_id"].int
             else { return print("updateBattleCell JSON is wrong") }
         guard let battle = store.battle()
             else { return print("Battle is invalid.") }
index 8366239..1ea39c3 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 class MasterShipMapper: JSONMapper {
     typealias ObjectType = MasterShip
@@ -24,10 +25,10 @@ class MasterShipMapper: JSONMapper {
         return ServerDataStore.default.sortedMasterSTypesById()
     }()
     
-    func handleExtraValue(_ value: Any, forKey key: String, to masterShip: MasterShip) -> Bool {
+    func handleExtraValue(_ value: JSON, forKey key: String, to masterShip: MasterShip) -> Bool {
         if key != "api_stype" { return false }
         
-        guard let sType = value as? Int
+        guard let sType = value.int
             else {
                 print("MasterShipMapper: value is not Int")
                 return false
index 339ec5f..7c0d22a 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 fileprivate enum MaterialAPI: String {
     case port = "/kcsapi/api_port/port"
@@ -47,17 +48,17 @@ class MaterialMapper: JSONMapper {
     }
     
     func commit() {
-        let j = apiResponse.json as NSDictionary
-        guard let data = j.value(forKeyPath: configuration.dataKey)
-            else { return print("JSON is wrong") }
         guard let store = configuration.editorStore as? ServerDataStore,
             let material = store.material() ?? store.createMaterial()
             else { return print("Can not create Material") }
         
-        switch data {
-        case let array as [Int]: register(material, data: array)
-        case let array as [[String: Any]]: register(material, data: array)
-        default: print("JSON is unknown type")
+        if let _ = data[0].int {
+            let array = data.arrayValue.flatMap { $0.int }
+            register(material, data: array)
+        } else if let _ = data[0].dictionary {
+            register(material, data: data.arrayValue)
+        } else {
+            print("JSON is unknown type")
         }
     }
     
@@ -68,12 +69,12 @@ class MaterialMapper: JSONMapper {
             material.setValue($0.element as NSNumber, forKey: keys[$0.offset])
         }
     }
-    private func register(_ material: Material, data: [[String: Any]]) {
+    private func register(_ material: Material, data: [JSON]) {
         data.forEach {
-            guard let i = $0["api_id"] as? Int,
+            guard let i = $0["api_id"].int,
                 i != 0,
                 i - 1 < keys.count,
-                let newValue = $0["api_value"] as? Int
+                let newValue = $0["api_value"].int
                 else { return }
             material.setValue(newValue as NSNumber, forKey: keys[i - 1])
         }
index 8f9cbf6..2d2649f 100644 (file)
@@ -19,46 +19,40 @@ class QuestListCommand: JSONCommand {
             tab == 0
             else { return }
         
-        let j = json as NSDictionary
-        guard let data = j.value(forKeyPath: dataKey) as? [String: Any],
-            let questList = data["api_list"] as? [Any],
-            let ql0 = questList.first as? [String: Any],
-            let ql0No = ql0["api_no"] as? Int,
-            let pageCount = data["api_page_count"] as? Int,
-            let page = data["api_disp_page"] as? Int
+        guard let ql0No = data["api_list"][0]["api_no"].int,
+            let pageCount = data["api_page_count"].int,
+            let page = data["api_disp_page"].int
             else { return print("data is wrong") }
         
         let store = ServerDataStore.oneTimeEditor()
         
         // 範囲内の任務をいったん遂行中からはずす
-        let qlm = questList.last as? [String: Any]
-        let qlmNo = qlm?["api_no"] as? Int ?? 9999
+        let qlmNo = data["api_list"].last["api_no"].int ?? 9999
         let minNo = (page == 1) ? 0 : ql0No
         let maxNo = (page == pageCount) ? 9999 : qlmNo
         store.quests(in: minNo...maxNo).forEach { $0.state = 1 }
         
         // 新しいデータ投入
         let quests = store.sortedQuestByNo()
-        questList.forEach {
-            guard let questData = $0 as? [String: Any],
-                let no = questData["api_no"] as? Int
+        data["api_list"].forEach { (_, quest) in
+            guard let no = quest["api_no"].int
             else { return }
             let t = quests.binarySearch { $0.no ==? no }
             guard let new = t ?? store.createQuest()
                 else { return print("Can not create Quest") }
-            new.bonus_flag = questData["api_bonus_flag"] as? Bool ?? false
-            new.category = questData["api_category"] as? Int ?? 0
-            new.detail = questData["api_detail"] as? String ?? ""
+            new.bonus_flag = quest["api_bonus_flag"].bool ?? false
+            new.category = quest["api_category"].int ?? 0
+            new.detail = quest["api_detail"].string ?? ""
 //            new.get_material_0 = questData["api_get_material_0"] as? Int ?? 0
 //            new.get_material_1 = questData["api_get_material_1"] as? Int ?? 0
 //            new.get_material_2 = questData["api_get_material_2"] as? Int ?? 0
 //            new.get_material_3 = questData["api_get_material_3"] as? Int ?? 0
-            new.invalid_flag = questData["api_invalid_flag"] as? Int ?? 0
-            new.no = questData["api_no"] as? Int ?? 0
-            new.progress_flag = questData["api_progress_flag"] as? Int ?? 0
-            new.state = questData["api_state"] as? Int ?? 0
-            new.title = questData["api_title"] as? String ?? ""
-            new.type = questData["api_type"] as? Int ?? 0
+            new.invalid_flag = quest["api_invalid_flag"].int ?? 0
+            new.no = quest["api_no"].int ?? 0
+            new.progress_flag = quest["api_progress_flag"].int ?? 0
+            new.state = quest["api_state"].int ?? 0
+            new.title = quest["api_title"].string ?? ""
+            new.type = quest["api_type"].int ?? 0
         }
     }
 }
index cdfa79c..10c7b0a 100644 (file)
@@ -10,36 +10,33 @@ import Cocoa
 
 class RemodelSlotItemCommand: JSONCommand {
     override func execute() {
-        guard let data = json[dataKey] as? [String: Any]
-            else { return print("JSON is wrong") }
-        
-        guard let success = data["api_remodel_flag"] as? Int,
+        guard let success = data["api_remodel_flag"].int,
             success != 0
             else { return }
         
-        guard let slotItemId = arguments["api_slot_id"].flatMap({ Int($0) }),
-            let afterSlot = data["api_after_slot"] as? [String: Any]
+        guard let slotItemId = arguments["api_slot_id"].flatMap({ Int($0) })
             else { return print("api_slot_id is wrong") }
         
+        let afterSlot = data["api_after_slot"]
         let store = ServerDataStore.oneTimeEditor()
         guard let slotItem = store.slotItem(byId: slotItemId)
             else { return print("SlotItem not found") }
 
-        if let locked = afterSlot["api_locked"] as? Bool {
+        if let locked = afterSlot["api_locked"].bool {
             slotItem.locked = locked
         }
-        if let masterSlotItemId = afterSlot["api_slotitem_id"] as? Int,
+        if let masterSlotItemId = afterSlot["api_slotitem_id"].int,
             masterSlotItemId != slotItem.slotitem_id,
             let masterSlotItem = store.masterSlotItem(by: slotItemId) {
             slotItem.master_slotItem = masterSlotItem
             slotItem.slotitem_id = slotItemId
         }
-        if let level = afterSlot["api_level"] as? Int {
+        if let level = afterSlot["api_level"].int {
             slotItem.level = level
         }
         
         // remove used slot items.
-        guard let useSlot = data["api_use_slot_id"] as? [Int]
+        guard let useSlot = data["api_use_slot_id"].arrayObject as? [Int]
             else { return }
         store.slotItems(in: useSlot).forEach { store.delete($0) }
     }
index 857deb6..3b4f148 100644 (file)
@@ -19,17 +19,15 @@ class SetPlaneCommand: JSONCommand {
             let rId = arguments["api_base_id"].flatMap({ Int($0) }),
             let squadronId = arguments["api_squadron_id"].flatMap({ Int($0) })
             else { return print("Argument is wrong") }
-        guard let data = json[dataKey] as? [String: Any],
-            let distance = data["api_distance"] as? Int,
-            let bauxite = data["api_after_bauxite"] as? Int,
-            let planInfos = data["api_plane_info"] as? [[String: Any]],
-            let planInfo = planInfos.first
+        guard let distance = data["api_distance"].int,
+            let bauxite = data["api_after_bauxite"].int
             else { return print("JSON is wrong") }
-        guard let cond = planInfo["api_cond"] as? Int,
-            let slotid = planInfo["api_slotid"] as? Int,
-            let state = planInfo["api_state"] as? Int,
-            let count = planInfo["api_count"] as? Int,
-            let maxCount = planInfo["api_max_count"] as? Int
+        let planInfo = data["api_plane_info"][0]
+        guard let cond = planInfo["api_cond"].int,
+            let slotid = planInfo["api_slotid"].int,
+            let state = planInfo["api_state"].int,
+            let count = planInfo["api_count"].int,
+            let maxCount = planInfo["api_max_count"].int
             else { return print("api_plane_info is wrong") }
         
         let store = ServerDataStore.oneTimeEditor()
index 744a97b..cb5f47e 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 fileprivate enum ShipAPI: String {
     case getMemberShip = "/kcsapi/api_get_member/ship"
@@ -100,36 +101,33 @@ class ShipMapper: JSONMapper {
     func beginRegister(_ ship: Ship) {
         ship.sally_area = nil
     }
-    func handleExtraValue(_ value: Any, forKey key: String, to ship: Ship) -> Bool {
+    func handleExtraValue(_ value: JSON, forKey key: String, to ship: Ship) -> Bool {
         // 取得後破棄した装備のデータを削除するため保有IDを保存
         if key == "api_id" {
-            guard let id = value as? Int
+            guard let id = value.int
                 else { return false }
             registerIds.append(id)
             return false
         }
         
         if key == "api_ship_id" {
-            guard let masterId = value as? Int
+            guard let masterId = value.int
                 else { return false }
             setMaster(masterId, to: ship)
             return true
         }
         if key == "api_exp" {
-            guard let v = value as? [Any],
-                let vv = v.first as? Int
+            guard let exp = value[0].int
                 else { return false }
-            ship.exp = vv
+            ship.exp = exp
             return true
         }
         if key == "api_slot" {
-            guard let slotItems = value as? [Any]
-                else { return false }
-            setSlot(slotItems, to: ship)
+            setSlot(value, to: ship)
             return false
         }
         if key == "api_slot_ex" {
-            guard let ex = value as? Int
+            guard let ex = value.int
                 else { return false }
             setExtraSlot(ex, to: ship)
             return false
@@ -151,8 +149,8 @@ class ShipMapper: JSONMapper {
         ship.ship_id = masterId
     }
     
-    private func setSlot(_ slotItems: [Any], to ship: Ship) {
-        guard let converSlotItems = slotItems as? [Int],
+    private func setSlot(_ slotItems: JSON, to ship: Ship) {
+        guard let converSlotItems = slotItems.arrayObject as? [Int],
             let store = store
             else { return }
         let newItems: [SlotItem] =
index 9204a98..e98405f 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 fileprivate enum SlotItemAPI: String {
     case getMemberSlotItem = "/kcsapi/api_get_member/slot_item"
@@ -45,17 +46,17 @@ class SlotItemMapper: JSONMapper {
     func beginRegister(_ slotItem: SlotItem) {
         slotItem.alv = 0
     }
-    func handleExtraValue(_ value: Any, forKey key: String, to object: SlotItem) -> Bool {
+    func handleExtraValue(_ value: JSON, forKey key: String, to object: SlotItem) -> Bool {
         // 取得後破棄した装備のデータを削除するため保有IDを保存
         if key == "api_id" {
-            guard let id = value as? Int
+            guard let id = value.int
                 else { return false }
             registerIds.append(id)
             return false
         }
         
         if key == "api_slotitem_id" {
-            guard let id = value as? Int
+            guard let id = value.int
                 else { return false }
             setMaster(id, to: object)
             return true
index 2c9601a..d4c1e25 100644 (file)
@@ -20,8 +20,7 @@ class SlotResetCommand: JSONCommand {
             .flatMap({ Int($0) })
             .flatMap({ store.ship(byId: $0) })
             else { return print("api_id is wrong") }
-        guard let sl = json["api_data"] as? [String: Any],
-            let slotItems = sl["api_slot"] as? [Int]
+        guard let slotItems = data["api_slot"].arrayObject as? [Int]
             else { return print("Can not parse api_data.api_slot") }
         
         slotItems.enumerated().forEach { ship.setItem($0.element, for: $0.offset) }
index 54f8be0..895d836 100644 (file)
@@ -7,6 +7,7 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
 class StoreCreateSlotItemHistoryCommand: JSONCommand {
     override func execute() {
@@ -16,8 +17,7 @@ class StoreCreateSlotItemHistoryCommand: JSONCommand {
             let bauxite = arguments["api_item4"].flatMap({ Int($0) })
             else { return print("Parameter is Wrong") }
         
-        guard let data = json[dataKey] as? [String: Any],
-            let success = data["api_create_flag"] as? Bool
+        guard let success = data["api_create_flag"].bool
             else { return print("api_create_flag is wrong") }
         let name = masterSlotItemName(sccess: success, data: data)
         let numberOfUsedKaihatuSizai = success ? 1 : 0
@@ -45,12 +45,11 @@ class StoreCreateSlotItemHistoryCommand: JSONCommand {
         newHistory.date = Date()
     }
     
-    private func masterSlotItemName(sccess: Bool, data: [String: Any]) -> String {
+    private func masterSlotItemName(sccess: Bool, data: JSON) -> String {
         if !sccess {
             return NSLocalizedString("fail to develop", comment: "fail to develop")
         }
-        guard let si = data["api_slot_item"] as? [String: Any],
-            let slotItemId = si["api_slotitem_id"] as? Int
+        guard let slotItemId = data["api_slot_item"]["api_slotitem_id"].int
             else {
                 print("api_slotitem_id is wrong")
                 return ""
index c39abc2..f6f6f67 100644 (file)
@@ -10,12 +10,10 @@ import Cocoa
 
 class UpdateSlotItemCommand: JSONCommand {
     override func execute() {
-        guard let d = json["api_data"] as? [String: Any]
-            else { return print("api_data is wrong") }
-        guard let data = d["api_slot_item"] as? [String: Any],
-            let slotItemId = data["api_slotitem_id"] as? Int
+        let data = json["api_data"]["api_slot_item"]
+        guard let slotItemId = data["api_slotitem_id"].int
             else { return }
-        guard let newSlotItemId = data["api_id"] as? Int
+        guard let newSlotItemId = data["api_id"].int
             else { return print("api_id is wrong") }
         let store = ServerDataStore.oneTimeEditor()
         guard let masterSlotItem = store.masterSlotItem(by: slotItemId)
index 6a74d8d..02e16ab 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ checkLocalizable:
 deploy:
        test -z "`git status --porcelain`"
 
-release: updateRevision
+release: Carthage updateRevision
        xcodebuild -derivedDataPath=build -configuration $(DEPLOYMENT)
        $(MAKE) restoreInfoPlist
 
@@ -61,3 +61,7 @@ build/Release/EquipmentEnhancementListBuilder: EquipmentEnhancementListBuilder/m
 
 buildEquipmentEnhancementList: build/Release/EquipmentEnhancementListBuilder
        ./build/Release/EquipmentEnhancementListBuilder ./KCD
+
+Carthage:
+       carthage update
+       rm -rf Carthage/Build/*OS