OSDN Git Service

MappingConfigurationをジェネリクスにした
authormasakih <masakih@users.sourceforge.jp>
Sun, 12 Mar 2017 01:33:21 +0000 (10:33 +0900)
committermasakih <masakih@users.sourceforge.jp>
Sun, 12 Mar 2017 01:33:21 +0000 (10:33 +0900)
19 files changed:
KCD.xcodeproj/project.pbxproj
KCD/AirBaseMapper.swift
KCD/BasicMapper.swift
KCD/DeckMapper.swift
KCD/JSONMapper.swift
KCD/KenzoDockMapper.swift
KCD/MasterFurnitureMapper.swift
KCD/MasterMapAreaMapper.swift
KCD/MasterMapInfoMapper.swift
KCD/MasterMissionMapper.swift
KCD/MasterSTypeMapper.swift
KCD/MasterShipMapper.swift
KCD/MasterSlotItemEquipTypeMapper.swift
KCD/MasterSlotItemMapper.swift
KCD/MasterUseItemMapper.swift
KCD/MaterialMapper.swift
KCD/NyukyoDockMapper.swift
KCD/ShipMapper.swift
KCD/SlotItemMapper.swift

index e7818e3..728e567 100644 (file)
                        isa = PBXGroup;
                        children = (
                                F47C3E971E5DB29300D97449 /* JSONMapper.swift */,
-                               F47C3E991E5DC90000D97449 /* MasterSTypeMapper.swift */,
+                               F47C3EBB1E61AEC500D97449 /* AirBaseMapper.swift */,
+                               F47C3EB51E60766000D97449 /* BasicMapper.swift */,
+                               F47C3EAD1E5F26E900D97449 /* DeckMapper.swift */,
+                               F47C3EB91E619CC400D97449 /* KenzoDockMapper.swift */,
                                F47C3EA31E5F017500D97449 /* MasterFurnitureMapper.swift */,
-                               F47C3E9B1E5DC94E00D97449 /* MasterShipMapper.swift */,
                                F47C3E9D1E5DD3E400D97449 /* MasterMapAreaMapper.swift */,
                                F47C3E9F1E5DE08F00D97449 /* MasterMapInfoMapper.swift */,
-                               F47C3EA11E5EFCC800D97449 /* MasterUseItemMapper.swift */,
-                               F47C3EA51E5F050D00D97449 /* MasterSlotItemMapper.swift */,
-                               F47C3EA71E5F06E700D97449 /* MasterSlotItemEquipTypeMapper.swift */,
                                F47C3EA91E5F085B00D97449 /* MasterMissionMapper.swift */,
-                               F47C3EB51E60766000D97449 /* BasicMapper.swift */,
-                               F47C3EAB1E5F1AD900D97449 /* ShipMapper.swift */,
-                               F47C3EAD1E5F26E900D97449 /* DeckMapper.swift */,
+                               F47C3E9B1E5DC94E00D97449 /* MasterShipMapper.swift */,
+                               F47C3EA71E5F06E700D97449 /* MasterSlotItemEquipTypeMapper.swift */,
+                               F47C3EA51E5F050D00D97449 /* MasterSlotItemMapper.swift */,
+                               F47C3E991E5DC90000D97449 /* MasterSTypeMapper.swift */,
+                               F47C3EA11E5EFCC800D97449 /* MasterUseItemMapper.swift */,
                                F47C3EAF1E60500700D97449 /* MaterialMapper.swift */,
                                F47C3EB11E60616E00D97449 /* NyukyoDockMapper.swift */,
+                               F47C3EAB1E5F1AD900D97449 /* ShipMapper.swift */,
                                F47C3EB71E61967C00D97449 /* SlotItemMapper.swift */,
-                               F47C3EB91E619CC400D97449 /* KenzoDockMapper.swift */,
-                               F47C3EBB1E61AEC500D97449 /* AirBaseMapper.swift */,
                        );
                        name = JSONMapper;
                        sourceTree = "<group>";
index 4e211df..7940dda 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class AirBaseMapper: JSONMapper {
+    typealias ObjectType = AirBase
+    
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: AirBase.self,
+    let configuration = MappingConfiguration(entity: AirBase.entity,
                                              dataKey: "api_data.api_air_base",
                                              compositPrimaryKeys: ["area_id", "rid"],
                                              editorStore: ServerDataStore.oneTimeEditor())
@@ -19,13 +21,9 @@ class AirBaseMapper: JSONMapper {
         self.apiResponse = apiResponse
     }
 
-    func handleExtraValue(_ value: Any, forKey key: String, to object: NSManagedObject) -> Bool {
+    func handleExtraValue(_ value: Any, forKey key: String, to airbase: AirBase) -> Bool {
         if key != "api_plane_info" { return false }
         
-        guard let airbase = object as? AirBase else {
-            print("object is not AirBase")
-            return false
-        }
         if airbase.planeInfo.count == 0 {
             if let store = configuration.editorStore as? ServerDataStore {
                 let new: [AirBasePlaneInfo] = (0..<4).flatMap {_ in
index 80f5e1c..90b4441 100644 (file)
@@ -23,12 +23,14 @@ fileprivate func dataKey(_ apiResponse: APIResponse) -> String {
 }
 
 class BasicMapper: JSONMapper {
+    typealias ObjectType = Basic
+    
     let apiResponse: APIResponse
-    let configuration: MappingConfiguration
+    let configuration: MappingConfiguration<Basic>
     
     required init(_ apiResponse: APIResponse) {
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entityType: Basic.self,
+        self.configuration = MappingConfiguration(entity: Basic.entity,
                                                   dataKey: dataKey(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor())
     }
index 27d9305..d4bb9a2 100644 (file)
@@ -33,12 +33,14 @@ fileprivate func dataKey(_ apiResponse: APIResponse) -> String {
 }
 
 class DeckMapper: JSONMapper {
+    typealias ObjectType = Deck
+    
     let apiResponse: APIResponse
-    let configuration: MappingConfiguration
+    let configuration: MappingConfiguration<Deck>
     
     required init(_ apiResponse: APIResponse) {
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entityType: Deck.self,
+        self.configuration = MappingConfiguration(entity: Deck.entity,
                                                   dataKey: dataKey(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor())
     }
index 0ddcae6..aa380e3 100644 (file)
@@ -8,21 +8,21 @@
 
 import Cocoa
 
-struct MappingConfiguration {
-    let entityType: NSManagedObject.Type
+struct MappingConfiguration<T: NSManagedObject> {
+    let entity: Entity<T>
     let dataKey: String
     let primaryKey: String
     let compositPrimaryKeys: [String]?
     let editorStore: CoreDataAccessor
     let ignoreKeys: [String]
     
-    init(entityType: NSManagedObject.Type,
+    init(entity: Entity<T>,
          dataKey: String = "api_data",
          primaryKey: String = "id",
          compositPrimaryKeys: [String]? = nil,
          editorStore: CoreDataAccessor,
          ignoreKeys: [String] = []) {
-        self.entityType = entityType
+        self.entity = entity
         self.dataKey = dataKey
         self.primaryKey = primaryKey
         self.compositPrimaryKeys = compositPrimaryKeys
@@ -32,15 +32,17 @@ struct MappingConfiguration {
 }
 
 protocol JSONMapper {
+    associatedtype ObjectType: NSManagedObject
+    
     init(_ apiResponse: APIResponse)
     
     var apiResponse: APIResponse { get }
-    var configuration: MappingConfiguration { get }
+    var configuration: MappingConfiguration<ObjectType> { get }
     
-    func registerElement(_ element: [String: Any], to object: NSManagedObject)
+    func registerElement(_ element: [String: Any], to object: ObjectType)
     func commit()
-    func beginRegister(_ object: NSManagedObject)
-    func handleExtraValue(_ value: Any, forKey key: String, to object: NSManagedObject) -> Bool
+    func beginRegister(_ object: ObjectType)
+    func handleExtraValue(_ value: Any, forKey key: String, to object: ObjectType) -> Bool
     func finishOperating()
 }
 
@@ -58,7 +60,7 @@ extension JSONMapper {
         if let aa = a, let bb = b { return aa.isEqual(bb) }
         return false
     }
-    func setValueIfNeeded(_ value: AnyObject?, to object: NSManagedObject, forKey key: String) {
+    func setValueIfNeeded(_ value: AnyObject?, to object: ObjectType, forKey key: String) {
         var validValue = value
         do { try object.validateValue(&validValue, forKey: key) }
         catch { return }
@@ -71,7 +73,7 @@ extension JSONMapper {
         }
     }
     
-    func registerElement(_ element: [String: Any], to object: NSManagedObject) {
+    func registerElement(_ element: [String: Any], to object: ObjectType) {
         beginRegister(object)
         element.forEach { (key: String, value: Any) in
             if configuration.ignoreKeys.contains(key) { return }
@@ -96,7 +98,7 @@ extension JSONMapper {
         let keys = configuration.compositPrimaryKeys ?? [configuration.primaryKey]
         return keys.map { NSSortDescriptor(key: $0, ascending: true) }
     }
-    private func objectSearch(_ objects: [NSManagedObject], _ element: [String: Any]) -> NSManagedObject? {
+    private func objectSearch(_ objects: [ObjectType], _ element: [String: Any]) -> ObjectType? {
         let keys = configuration.compositPrimaryKeys ?? [configuration.primaryKey]
         let keyPiar = keys.map { (key: $0, apiKey: "api_\($0)") }
         return objects.binarySearch {
@@ -118,17 +120,15 @@ extension JSONMapper {
             else { return print("JSON is wrong.") }
         
         let store = configuration.editorStore
-        let entity = Entity(name: configuration.entityType.entityName,
-                            type: configuration.entityType)
-        guard let objects = try? store.objects(with: entity, sortDescriptors: sortDescriptors)
-            else { return print("Can not get entity named \(configuration.entityType.entityName)") }
+        guard let objects = try? store.objects(with: configuration.entity, sortDescriptors: sortDescriptors)
+            else { return print("Can not get entity named \(configuration.entity.name)") }
         data.forEach {
             if let object = objectSearch(objects, $0) {
                 registerElement($0, to: object)
-            } else if let new = store.insertNewObject(for: entity) {
+            } else if let new = store.insertNewObject(for: configuration.entity) {
                 registerElement($0, to: new)
             } else {
-                fatalError("Can not create Entity")
+                fatalError("Can not get entity named \(configuration.entity.name)")
             }
         }
         finishOperating()
@@ -136,8 +136,8 @@ extension JSONMapper {
     }
     
     func execute() {}
-    func beginRegister(_ object: NSManagedObject) {}
-    func handleExtraValue(_ value: Any, forKey key: String, to object: NSManagedObject) -> Bool {
+    func beginRegister(_ object: ObjectType) {}
+    func handleExtraValue(_ value: Any, forKey key: String, to object: ObjectType) -> Bool {
         return false
     }
     func finishOperating() {}
index a0c2773..106504a 100644 (file)
@@ -25,12 +25,13 @@ fileprivate func dataKey(_ apiResponse: APIResponse) -> String {
 }
 
 class KenzoDockMapper: JSONMapper {
+    typealias ObjectType = KenzoDock
     let apiResponse: APIResponse
-    let configuration: MappingConfiguration
+    let configuration: MappingConfiguration<KenzoDock>
     
     required init(_ apiResponse: APIResponse) {
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entityType: KenzoDock.self,
+        self.configuration = MappingConfiguration(entity: KenzoDock.entity,
                                                   dataKey: dataKey(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor())
     }
index 2ec88c9..2df11c0 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterFurnitureMapper: JSONMapper {
+    typealias ObjectType = MasterFurniture
+
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterFurniture.self,
+    let configuration = MappingConfiguration(entity: MasterFurniture.entity,
                                              dataKey: "api_data.api_mst_furniture",
                                              editorStore: ServerDataStore.oneTimeEditor(),
                                              ignoreKeys: ["api_season"])
index a75b0cc..2a2d71e 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterMapAreaMapper: JSONMapper {
+    typealias ObjectType = MasterMapArea
+    
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterMapArea.self,
+    let configuration = MappingConfiguration(entity: MasterMapArea.entity,
                                              dataKey: "api_data.api_mst_maparea",
                                              editorStore: ServerDataStore.oneTimeEditor())
     
index fc3d23c..c7049d6 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterMapInfoMapper: JSONMapper {
+    typealias ObjectType = MasterMapInfo
+    
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterMapInfo.self,
+    let configuration = MappingConfiguration(entity: MasterMapInfo.entity,
                                              dataKey: "api_data.api_mst_mapinfo",
                                              editorStore: ServerDataStore.oneTimeEditor())
     
index 3fb7729..6c54358 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterMissionMapper: JSONMapper {
+    typealias ObjectType = MasterMission
+
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterMission.self,
+    let configuration = MappingConfiguration(entity: MasterMission.entity,
                                              dataKey: "api_data.api_mst_mission",
                                              editorStore: ServerDataStore.oneTimeEditor())
     
index 4e150ec..d2559ae 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterSTypeMapper: JSONMapper {
+    typealias ObjectType = MasterSType
+
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterSType.self,
+    let configuration = MappingConfiguration(entity: MasterSType.entity,
                                              dataKey: "api_data.api_mst_stype",
                                              editorStore: ServerDataStore.oneTimeEditor(),
                                              ignoreKeys: ["api_equip_type"])
index d46847b..8366239 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterShipMapper: JSONMapper {
+    typealias ObjectType = MasterShip
+    
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterShip.self,
+    let configuration = MappingConfiguration(entity: MasterShip.entity,
                                              dataKey: "api_data.api_mst_ship",
                                              editorStore: ServerDataStore.oneTimeEditor())
     
@@ -22,7 +24,7 @@ class MasterShipMapper: JSONMapper {
         return ServerDataStore.default.sortedMasterSTypesById()
     }()
     
-    func handleExtraValue(_ value: Any, forKey key: String, to object: NSManagedObject) -> Bool {
+    func handleExtraValue(_ value: Any, forKey key: String, to masterShip: MasterShip) -> Bool {
         if key != "api_stype" { return false }
         
         guard let sType = value as? Int
@@ -30,11 +32,6 @@ class MasterShipMapper: JSONMapper {
                 print("MasterShipMapper: value is not Int")
                 return false
         }
-        guard let masterShip = object as? MasterShip
-            else {
-                print("MasterShipMapper: object is not KCMasterShipObject")
-                return false
-        }
         setStype(sType, to: masterShip)
         return true
     }
index de4a60d..d6cc849 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterSlotItemEquipTypeMapper: JSONMapper {
+    typealias ObjectType = MasterSlotItemEquipType
+
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterSlotItemEquipType.self,
+    let configuration = MappingConfiguration(entity: MasterSlotItemEquipType.entity,
                                              dataKey: "api_data.api_mst_slotitem_equiptype",
                                              editorStore: ServerDataStore.oneTimeEditor())
     
index b4ff402..4ad91a7 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterSlotItemMapper: JSONMapper {
+    typealias ObjectType = MasterSlotItem
+
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterSlotItem.self,
+    let configuration = MappingConfiguration(entity: MasterSlotItem.entity,
                                              dataKey: "api_data.api_mst_slotitem",
                                              editorStore: ServerDataStore.oneTimeEditor())
     
index e115fff..d98cfe7 100644 (file)
@@ -9,8 +9,10 @@
 import Cocoa
 
 class MasterUseItemMapper: JSONMapper {
+    typealias ObjectType = MasterUseItem
+
     let apiResponse: APIResponse
-    let configuration = MappingConfiguration(entityType: MasterUseItem.self,
+    let configuration = MappingConfiguration(entity: MasterUseItem.entity,
                                              dataKey: "api_data.api_mst_useitem",
                                              editorStore: ServerDataStore.oneTimeEditor())
     
index 12efa97..339ec5f 100644 (file)
@@ -29,8 +29,10 @@ fileprivate func dataKey(_ apiResponse: APIResponse) -> String {
 }
 
 class MaterialMapper: JSONMapper {
+    typealias ObjectType = Material
+    
     let apiResponse: APIResponse
-    let configuration: MappingConfiguration
+    let configuration: MappingConfiguration<Material>
     
     private let keys = [
         "fuel", "bull", "steel", "bauxite",
@@ -39,7 +41,7 @@ class MaterialMapper: JSONMapper {
     
     required init(_ apiResponse: APIResponse) {
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entityType: Material.self,
+        self.configuration = MappingConfiguration(entity: Material.entity,
                                                   dataKey: dataKey(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor())
     }
index 9fd3271..2f1481c 100644 (file)
@@ -23,12 +23,14 @@ fileprivate func dataKey(_ apiResponse: APIResponse) -> String {
 }
 
 class NyukyoDockMapper: JSONMapper {
+    typealias ObjectType = NyukyoDock
+
     let apiResponse: APIResponse
-    let configuration: MappingConfiguration
+    let configuration: MappingConfiguration<NyukyoDock>
     
     required init(_ apiResponse: APIResponse) {
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entityType: NyukyoDock.self,
+        self.configuration = MappingConfiguration(entity: NyukyoDock.entity,
                                                   dataKey: dataKey(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor())
     }
index bf6b2d1..744a97b 100644 (file)
@@ -34,7 +34,7 @@ fileprivate func dataKey(_ apiResponse: APIResponse) -> String {
 
 extension MappingConfiguration {
     func change(dataKey: String) -> MappingConfiguration {
-        return MappingConfiguration(entityType: self.entityType,
+        return MappingConfiguration(entity: self.entity,
                                     dataKey: dataKey,
                                     primaryKey: self.primaryKey,
                                     compositPrimaryKeys: self.compositPrimaryKeys,
@@ -44,12 +44,13 @@ extension MappingConfiguration {
 }
 
 class ShipMapper: JSONMapper {
+    typealias ObjectType = Ship
     let apiResponse: APIResponse
-    let configuration: MappingConfiguration
+    let configuration: MappingConfiguration<Ship>
     
     required init(_ apiResponse: APIResponse) {
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entityType: Ship.self,
+        self.configuration = MappingConfiguration(entity: Ship.entity,
                                                   dataKey: dataKey(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor(),
                                                   ignoreKeys:
@@ -69,7 +70,7 @@ class ShipMapper: JSONMapper {
             ShipMapper(apiResponse, configuration: conf).commit()
         }
     }
-    private init(_ apiResponse: APIResponse, configuration: MappingConfiguration) {
+    private init(_ apiResponse: APIResponse, configuration: MappingConfiguration<Ship>) {
         self.apiResponse = apiResponse
         self.configuration = configuration
     }
@@ -96,15 +97,10 @@ class ShipMapper: JSONMapper {
         return configuration.editorStore as? ServerDataStore
     }
     
-    func beginRegister(_ object: NSManagedObject) {
-        guard let ship = object as? Ship
-            else { return }
+    func beginRegister(_ ship: Ship) {
         ship.sally_area = nil
     }
-    func handleExtraValue(_ value: Any, forKey key: String, to object: NSManagedObject) -> Bool {
-        guard let ship = object as? Ship
-            else { return false }
-        
+    func handleExtraValue(_ value: Any, forKey key: String, to ship: Ship) -> Bool {
         // 取得後破棄した装備のデータを削除するため保有IDを保存
         if key == "api_id" {
             guard let id = value as? Int
index 8807109..9204a98 100644 (file)
@@ -25,12 +25,14 @@ fileprivate func dataKey(_ apiResponse: APIResponse) -> String {
 }
 
 class SlotItemMapper: JSONMapper {
+    typealias ObjectType = SlotItem
+    
     let apiResponse: APIResponse
-    let configuration: MappingConfiguration
+    let configuration: MappingConfiguration<SlotItem>
     
     required init(_ apiResponse: APIResponse) {
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entityType: SlotItem.self,
+        self.configuration = MappingConfiguration(entity: SlotItem.entity,
                                                   dataKey: dataKey(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor())
     }
@@ -40,12 +42,10 @@ class SlotItemMapper: JSONMapper {
         return ServerDataStore.default.sortedMasterSlotItemsById()
     }()
     
-    func beginRegister(_ object: NSManagedObject) {
-        guard let slotItem = object as? SlotItem
-            else { return }
+    func beginRegister(_ slotItem: SlotItem) {
         slotItem.alv = 0
     }
-    func handleExtraValue(_ value: Any, forKey key: String, to object: NSManagedObject) -> Bool {
+    func handleExtraValue(_ value: Any, forKey key: String, to object: SlotItem) -> Bool {
         // 取得後破棄した装備のデータを削除するため保有IDを保存
         if key == "api_id" {
             guard let id = value as? Int
@@ -73,9 +73,9 @@ class SlotItemMapper: JSONMapper {
         store.slotItems(exclude: registerIds).forEach { store.delete($0) }
     }
     
-    private func setMaster(_ masterId: Int, to object: NSManagedObject?) {
-        guard let slotItem = object as? SlotItem
-            else { return print("argument is wrong") }
+    private func setMaster(_ masterId: Int, to slotItem: SlotItem?) {
+        guard let slotItem = slotItem
+            else { return }
         if slotItem.slotitem_id == masterId { return }
         
         guard let mSlotItem = masterSlotItems.binarySearch(comparator: { $0.id ==? masterId })