OSDN Git Service

staticプロパティをインスタンスプロパティに変更
[kcd/KCD.git] / KCD / JSONMapper.swift
index e865ccd..0536b8b 100644 (file)
@@ -8,20 +8,21 @@
 
 import Cocoa
 import SwiftyJSON
+import Doutaku
 
-struct MappingConfiguration<T: NSManagedObject> {
+struct MappingConfiguration<T: Entity> {
     
-    let entity: Entity<T>
+    let entity: T.Type
     let dataKeys: [String]
     let primaryKeys: [String]
     let editorStore: CoreDataAccessor
-    let ignoreKeys: [String]
+    let ignoreKeys: Set<String>
     
-    init(entity: Entity<T>,
+    init(entity: T.Type,
          dataKeys: [String] = ["api_data"],
          primaryKeys: [String] = ["id"],
          editorStore: CoreDataAccessor,
-         ignoreKeys: [String] = []) {
+         ignoreKeys: Set<String> = []) {
         
         self.entity = entity
         self.dataKeys = dataKeys
@@ -33,7 +34,7 @@ struct MappingConfiguration<T: NSManagedObject> {
 
 protocol JSONMapper {
     
-    associatedtype ObjectType: NSManagedObject
+    associatedtype ObjectType: Entity
     
     init(_ apiResponse: APIResponse)
     
@@ -48,14 +49,15 @@ protocol JSONMapper {
 }
 
 extension String {
-    
+    // delete api_ prefix.
     func keyByDeletingPrefix() -> String {
         
-        if self.characters.count < 5 { return self }
-        
-        let s = self.index(self.startIndex, offsetBy: 4)
+        if self.count < 5 {
+            
+            return self
+        }
         
-        return self[s..<self.endIndex]
+        return String(self[index(startIndex, offsetBy: 4)...])
     }
 }
 
@@ -65,8 +67,14 @@ extension JSONMapper {
     
     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) }
+        if lhs == nil, rhs == nil {
+            
+            return true
+        }
+        if let lhs = lhs, let rhs = rhs {
+            
+            return lhs.isEqual(rhs)
+        }
         
         return false
     }
@@ -81,17 +89,12 @@ extension JSONMapper {
         } catch {
             
             return
-            
         }
         
         let old = object.value(forKey: key)
         if !isEqual(old as AnyObject?, validValue) {
             
-            object.notifyChangeValue(forKey: key) {
-                
-                object.setValue(validValue, forKey: key)
-                
-            }
+            object.setValue(validValue, forKey: key)
         }
     }
     
@@ -100,8 +103,14 @@ extension JSONMapper {
         beginRegister(object)
         element.forEach { (key, value) in
             
-            if configuration.ignoreKeys.contains(key) { return }
-            if handleExtraValue(value, forKey: key, to: object) { return }
+            if configuration.ignoreKeys.contains(key) {
+                
+                return
+            }
+            if handleExtraValue(value, forKey: key, to: object) {
+                
+                return
+            }
             
             switch value.type {
             case .array:
@@ -117,9 +126,10 @@ extension JSONMapper {
                     let newKey = "\(key)_D_\(subKey.keyByDeletingPrefix())"
                     setValueIfNeeded(subValue, to: object, forKey: newKey)
                 }
-            default:
                 
+            default:
                 setValueIfNeeded(value, to: object, forKey: key)
+                
             }
         }
     }
@@ -138,10 +148,15 @@ extension JSONMapper {
             // TODO: replace to forEach
             for piar in keyPiar {
                 
-                guard let v1 = $0.value(forKey: piar.key)
-                    else { return .orderedAscending }
+                guard let v1 = $0.value(forKey: piar.key) else {
+                    
+                    return .orderedAscending
+                }
                 
-                if element[piar.apiKey].type == .null { return .orderedDescending }
+                if element[piar.apiKey].type == .null {
+                    
+                    return .orderedDescending
+                }
                 
                 let v2 = element[piar.apiKey].object
                 
@@ -152,12 +167,23 @@ extension JSONMapper {
         }
     }
     
-    func commit() {
+    private func sortedObjects<ResultType: Entity>(_ entity: ResultType.Type) -> [ResultType] {
         
         let store = configuration.editorStore
         
-        guard let objects = try? store.objects(of: configuration.entity, sortDescriptors: sortDescriptors)
-            else { return print("Can not get entity named \(configuration.entity.name)") }
+        guard let objects = try? store.objects(of: configuration.entity) else {
+            
+            Logger.shared.log("Can not get entity named \(configuration.entity)")
+            
+            return []
+        }
+        
+        return (objects as NSArray).sortedArray(using: sortDescriptors) as? [ResultType] ?? []
+    }
+    private func commintInContext() {
+        
+        let store = configuration.editorStore
+        let objects = sortedObjects(configuration.entity)
         
         let list = (data.type == .array ? data.arrayValue : [data])
         list.forEach {
@@ -172,8 +198,7 @@ extension JSONMapper {
                 
             } else {
                 
-                fatalError("Can not get entity named \(configuration.entity.name)")
-                
+                fatalError("Can not get entity named \(configuration.entity)")
             }
         }
         
@@ -181,6 +206,15 @@ extension JSONMapper {
         store.save()
     }
     
+    func commit() {
+        
+        configuration.editorStore
+            .sync {
+                
+                self.commintInContext()
+        }
+    }
+    
     func beginRegister(_ object: ObjectType) {}
     
     func handleExtraValue(_ value: JSON, forKey key: String, to object: ObjectType) -> Bool {