【问题标题】:CoreData desired type = NSManagedObject; given type = __NSSingleObjectSetICoreData 所需类型 = NSManagedObject;给定类型 = __NSSingleObjectSetI
【发布时间】:2019-06-19 10:08:38
【问题描述】:

我正在使用 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)
    }

【问题讨论】:

    标签: ios swift core-data database-migration core-data-migration


    【解决方案1】:

    我用 NSEntityDescription 替换了自定义类并使用了 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)
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多