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
protocol JSONMapper {
- associatedtype ObjectType: NSManagedObject
+ associatedtype ObjectType: Entity
init(_ apiResponse: APIResponse)
}
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)...])
}
}
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
}
} 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)
}
}
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:
let newKey = "\(key)_D_\(subKey.keyByDeletingPrefix())"
setValueIfNeeded(subValue, to: object, forKey: newKey)
}
- default:
+ default:
setValueIfNeeded(value, to: object, forKey: key)
+
}
}
}
// 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
}
}
- 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 {
} else {
- fatalError("Can not get entity named \(configuration.entity.name)")
-
+ fatalError("Can not get entity named \(configuration.entity)")
}
}
store.save()
}
+ func commit() {
+
+ configuration.editorStore
+ .sync {
+
+ self.commintInContext()
+ }
+ }
+
func beginRegister(_ object: ObjectType) {}
func handleExtraValue(_ value: JSON, forKey key: String, to object: ObjectType) -> Bool {