OSDN Git Service

コメントを追加
[kcd/KCD.git] / KCD / MaterialMapper.swift
index 339ec5f..c80c775 100644 (file)
@@ -7,74 +7,79 @@
 //
 
 import Cocoa
+import SwiftyJSON
 
-fileprivate enum MaterialAPI: String {
-    case port = "/kcsapi/api_port/port"
-    case kousyouCreateItem = "/kcsapi/api_req_kousyou/createitem"
-    case kousyouDestoroyShip = "/kcsapi/api_req_kousyou/destroyship"
-    case kousyouRemodelSlot = "/kcsapi/api_req_kousyou/remodel_slot"
-    case hokyuCharge = "/kcsapi/api_req_hokyu/charge"
-}
-
-fileprivate func dataKey(_ apiResponse: APIResponse) -> String {
-    guard let materialApi = MaterialAPI(rawValue: apiResponse.api)
-        else { return "api_data" }
-    switch materialApi {
-    case .port: return "api_data.api_material"
-    case .kousyouCreateItem: return "api_data.api_material"
-    case .kousyouDestoroyShip: return "api_data.api_material"
-    case .kousyouRemodelSlot: return "api_data.api_after_material"
-    case .hokyuCharge: return "api_data.api_material"
-    }
-}
-
-class MaterialMapper: JSONMapper {
-    typealias ObjectType = Material
-    
+final class MaterialMapper: JSONMapper {
+        
     let apiResponse: APIResponse
     let configuration: MappingConfiguration<Material>
     
     private let keys = [
-        "fuel", "bull", "steel", "bauxite",
-        "kousokukenzo", "kousokushuhuku", "kaihatusizai", "screw"
+        #keyPath(Material.fuel), #keyPath(Material.bull), #keyPath(Material.steel), #keyPath(Material.bauxite),
+        #keyPath(Material.kousokukenzo), #keyPath(Material.kousokushuhuku), #keyPath(Material.kaihatusizai), #keyPath(Material.screw)
     ]
     
     required init(_ apiResponse: APIResponse) {
+        
         self.apiResponse = apiResponse
         self.configuration = MappingConfiguration(entity: Material.entity,
-                                                  dataKey: dataKey(apiResponse),
+                                                  dataKeys: MaterialMapper.dataKeys(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor())
     }
     
+    private class func dataKeys(_ apiResponse: APIResponse) -> [String] {
+                
+        switch apiResponse.api.endpoint {
+            
+        case .material: return ["api_data"]
+            
+        case .port, .createItem, .destroyShip, .charge: return ["api_data", "api_material"]
+            
+        case .remodelSlot: return ["api_data", "api_after_material"]
+            
+        default: return Logger.shared.log("Missing API: \(apiResponse.api)", value: ["api_data"])
+        }
+    }
+    
     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") }
+            let material = store.material() ?? store.createMaterial() else {
+                
+                return Logger.shared.log("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")
+            
         }
     }
     
     private func register(_ material: Material, data: [Int]) {
-        data.enumerated().forEach {
-            guard $0.offset < keys.count
-                else { return }
-            material.setValue($0.element as NSNumber, forKey: keys[$0.offset])
+        
+        zip(data, keys).forEach {
+            
+            material.setValue($0, forKey: $1)
         }
     }
-    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,
-                i != 0,
-                i - 1 < keys.count,
-                let newValue = $0["api_value"] as? Int
-                else { return }
+            
+            guard let i = $0["api_id"].int, case 1...keys.count = i else { return }
+            guard let newValue = $0["api_value"].int else { return }
+            
             material.setValue(newValue as NSNumber, forKey: keys[i - 1])
         }
     }