CoreData 所需类型 = NSManagedObject;给定类型 = __NSSingleObjectSetI
CoreData desired type = NSManagedObject; given type = __NSSingleObjectSetI
我正在使用 NSEntityMigrationPolicy
进行 CoreData 迁移,我需要在当前模型和迁移期间创建的模型之间建立关系。我根据当前模型给出的数据在 createDestinationInstances
中创建新模型,但是当我尝试建立关系时,出现此错误 desired type = NSManagedObject; given type = __NSSingleObjectSetI
关系是一对多
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
let sourceAttributeKeys = Array(sInstance.entity.attributesByName.keys)
let sourceAttributeValues = sInstance.dictionaryWithValues(forKeys: sourceAttributeKeys)
guard let baseRelativeUrlString = sourceAttributeValues["baseRelativeUrlString"] as? String, let fontFileNames = sourceAttributeValues["fontFileNames"] as? [String] else {
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
return
}
// Create the destination Note instance
let destinationInstance = NSEntityDescription.insertNewObject(forEntityName: mapping.destinationEntityName!, into: manager.destinationContext)
// Get the destination attribute keys
let destinationAttributeKeys = Array(destinationInstance.entity.attributesByName.keys)
for key in destinationAttributeKeys {
if let value = sourceAttributeValues[key] {
destinationInstance.setValue(value, forKey: key)
}
}
let appSupportUrl = FileSystemManager.appSupportURL
var array = [CustomFontData]()
for fontFileName in fontFileNames {
let url = appSupportUrl.appendingPathComponent(baseRelativeUrlString).appendingPathComponent(fontFileName)
do {
let fontData = try Data(contentsOf: url)
let fontDataName = fontFileName.components(separatedBy: ".")[0]
let customFontData = CustomFontData(context: manager.destinationContext)
customFontData.name = fontDataName
customFontData.data = fontData
array.append(customFontData)
} catch {
debugPrint(#function, error.localizedDescription)
BugHunter.shared.catchError(error, devInfo: [.functionName : #function])
}
}
destinationInstance.setValue(NSSet(array: array), forKey: "fontsData")
manager.associate(sourceInstance: sInstance, withDestinationInstance: destinationInstance, for: mapping)
}
我用 NSEntityDescription 替换了自定义 class 并使用了 KVO。
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
let sourceAttributeKeys = Array(sInstance.entity.attributesByName.keys)
let sourceAttributeValues = sInstance.dictionaryWithValues(forKeys: sourceAttributeKeys)
guard let baseRelativeUrlString = sourceAttributeValues["baseRelativeUrlString"] as? String, let fontFileNames = sourceAttributeValues["fontFileNames"] as? [String] else {
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
return
}
// Create the destination Note instance
let destinationInstance = NSEntityDescription.insertNewObject(forEntityName: mapping.destinationEntityName!, into: manager.destinationContext)
// Get the destination attribute keys
let destinationAttributeKeys = Array(destinationInstance.entity.attributesByName.keys)
for key in destinationAttributeKeys {
if let value = sourceAttributeValues[key] {
destinationInstance.setValue(value, forKey: key)
}
}
let appSupportUrl = FileSystemManager.appSupportURL
var array = [NSManagedObject]()
for fontFileName in fontFileNames {
let url = appSupportUrl.appendingPathComponent(baseRelativeUrlString).appendingPathComponent(fontFileName)
do {
let fontData = try Data(contentsOf: url)
let fontDataName = fontFileName.components(separatedBy: ".")[0]
let customFontData = NSEntityDescription.insertNewObject(forEntityName: CustomFontData.entityName, into: manager.destinationContext)
customFontData.setValue(fontDataName, forKey: "name")
customFontData.setValue(fontData, forKey: "data")
array.append(customFontData)
} catch {
debugPrint(#function, error.localizedDescription)
BugHunter.shared.catchError(error, devInfo: [.functionName : #function])
}
}
destinationInstance.setValue(NSSet(array: array), forKey: "fontsData")
manager.associate(sourceInstance: sInstance, withDestinationInstance: destinationInstance, for: mapping)
}
我正在使用 NSEntityMigrationPolicy
进行 CoreData 迁移,我需要在当前模型和迁移期间创建的模型之间建立关系。我根据当前模型给出的数据在 createDestinationInstances
中创建新模型,但是当我尝试建立关系时,出现此错误 desired type = NSManagedObject; given type = __NSSingleObjectSetI
关系是一对多
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
let sourceAttributeKeys = Array(sInstance.entity.attributesByName.keys)
let sourceAttributeValues = sInstance.dictionaryWithValues(forKeys: sourceAttributeKeys)
guard let baseRelativeUrlString = sourceAttributeValues["baseRelativeUrlString"] as? String, let fontFileNames = sourceAttributeValues["fontFileNames"] as? [String] else {
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
return
}
// Create the destination Note instance
let destinationInstance = NSEntityDescription.insertNewObject(forEntityName: mapping.destinationEntityName!, into: manager.destinationContext)
// Get the destination attribute keys
let destinationAttributeKeys = Array(destinationInstance.entity.attributesByName.keys)
for key in destinationAttributeKeys {
if let value = sourceAttributeValues[key] {
destinationInstance.setValue(value, forKey: key)
}
}
let appSupportUrl = FileSystemManager.appSupportURL
var array = [CustomFontData]()
for fontFileName in fontFileNames {
let url = appSupportUrl.appendingPathComponent(baseRelativeUrlString).appendingPathComponent(fontFileName)
do {
let fontData = try Data(contentsOf: url)
let fontDataName = fontFileName.components(separatedBy: ".")[0]
let customFontData = CustomFontData(context: manager.destinationContext)
customFontData.name = fontDataName
customFontData.data = fontData
array.append(customFontData)
} catch {
debugPrint(#function, error.localizedDescription)
BugHunter.shared.catchError(error, devInfo: [.functionName : #function])
}
}
destinationInstance.setValue(NSSet(array: array), forKey: "fontsData")
manager.associate(sourceInstance: sInstance, withDestinationInstance: destinationInstance, for: mapping)
}
我用 NSEntityDescription 替换了自定义 class 并使用了 KVO。
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
let sourceAttributeKeys = Array(sInstance.entity.attributesByName.keys)
let sourceAttributeValues = sInstance.dictionaryWithValues(forKeys: sourceAttributeKeys)
guard let baseRelativeUrlString = sourceAttributeValues["baseRelativeUrlString"] as? String, let fontFileNames = sourceAttributeValues["fontFileNames"] as? [String] else {
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
return
}
// Create the destination Note instance
let destinationInstance = NSEntityDescription.insertNewObject(forEntityName: mapping.destinationEntityName!, into: manager.destinationContext)
// Get the destination attribute keys
let destinationAttributeKeys = Array(destinationInstance.entity.attributesByName.keys)
for key in destinationAttributeKeys {
if let value = sourceAttributeValues[key] {
destinationInstance.setValue(value, forKey: key)
}
}
let appSupportUrl = FileSystemManager.appSupportURL
var array = [NSManagedObject]()
for fontFileName in fontFileNames {
let url = appSupportUrl.appendingPathComponent(baseRelativeUrlString).appendingPathComponent(fontFileName)
do {
let fontData = try Data(contentsOf: url)
let fontDataName = fontFileName.components(separatedBy: ".")[0]
let customFontData = NSEntityDescription.insertNewObject(forEntityName: CustomFontData.entityName, into: manager.destinationContext)
customFontData.setValue(fontDataName, forKey: "name")
customFontData.setValue(fontData, forKey: "data")
array.append(customFontData)
} catch {
debugPrint(#function, error.localizedDescription)
BugHunter.shared.catchError(error, devInfo: [.functionName : #function])
}
}
destinationInstance.setValue(NSSet(array: array), forKey: "fontsData")
manager.associate(sourceInstance: sInstance, withDestinationInstance: destinationInstance, for: mapping)
}