我正在做某事。如果它有帮助... PS:请使用泛型对其进行优化。
import Foundation
import CoreData
enum ModelInitializationResult {
case none
case completedWithoutErrors
case completedWithNullDataErrors
case completedWithNoSuchKeyErrors
}
extension NSManagedObject {
//Note: For this to work, the keys in the dictionary should be same as attibute name of this class
func initializeModelFromDictionary(dictionary: [String:Any] ) -> ModelInitializationResult{
var completionResult = ModelInitializationResult.none
let modelAttributes = self.entity.attributesByName
let modelAttributeKeys = modelAttributes.keys
for case let (keyToSet, valueToSet) in dictionary {
//check for invalid key
guard modelAttributeKeys.contains(keyToSet) else{
completionResult = .completedWithNoSuchKeyErrors
continue;
}
//check valueToSetType for Null
let valueToSetType = type(of: valueToSet)
guard valueToSetType != NSNull.self else{
print("ERROR: Found NSNUll for value to set")
completionResult = .completedWithNullDataErrors
continue;
}
//Check desiredType ; set value for defined types
let modelAttributeValue = modelAttributes[keyToSet]
let modelAttributeType = modelAttributeValue?.attributeType
switch (modelAttributeType!) {
case .undefinedAttributeType :
print("Error : undefinedAttributeType")
case .integer16AttributeType, .integer32AttributeType, .integer64AttributeType :
if let anInt = valueToSet as? Int{
self.setValue(anInt, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .stringAttributeType :
if let anString = valueToSet as? String{
self.setValue(anString, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .booleanAttributeType :
if let aBool = valueToSet as? Bool{
self.setValue(aBool, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .dateAttributeType :
if let aDate = valueToSet as? Date{
self.setValue(aDate, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .binaryDataAttributeType :
if let aData = valueToSet as? Data{
self.setValue(aData, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .transformableAttributeType :// If your attribute is of NSTransformableAttributeType,
//print(Pretty//printedFunction(), "desiredType : transformableAttributeType")
if let anObject = valueToSet as? NSObject {
self.setValue(anObject, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .doubleAttributeType :
//print(Pretty//printedFunction(), "desiredType : doubleAttributeType")
if let anObject = valueToSet as? Double {
self.setValue(anObject, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .floatAttributeType :
//print(Pretty//printedFunction(), "desiredType : floatAttributeType")
if let anObject = valueToSet as? Float {
self.setValue(anObject, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .decimalAttributeType :
print("Error: Data type decimalAttributeType Not handled\(String(describing: modelAttributeType))")
case .objectIDAttributeType:
print("Error: Data type transformableAttributeType Not handled\(String(describing: modelAttributeType))")
default :
print("ERROR : \(String(describing: modelAttributeType))")
}
}
return completionResult
}
func toDictionary() -> [String:Any] {
let keys = Array(self.entity.attributesByName.keys)
let dict = self.dictionaryWithValues(forKeys: keys)
return dict
}
func printAllValues (){
for key in self.entity.attributesByName.keys{
let value: Any? = self.value(forKey: key)
print("\(key) = \(String(describing: value))")
}
}
}