【问题标题】:Encoding/Decoding UIBezierPath to CoreData Issues编码/解码 UIBezierPath 到 CoreData 问题
【发布时间】:2021-11-02 04:02:35
【问题描述】:

我将 UIBezierPaths 存储在 CoreData 中。为此,我必须将字段的类型设置为数据;我无法让 Transformable 工作,但确实如此。

但是,当我检索或存储这些路径时,我在编码/解码过程中遇到了错误。错误是

2021-11-02 09:08:39.138674+0700 TestSVG[82461:1408543] [general] 'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release

根据此处提供的帮助,我使用的方法是:

 func bezierToData(path: UIBezierPath) -> Data? {
        do {
            return try NSKeyedArchiver.archivedData(withRootObject: path, requiringSecureCoding: false)
        } catch {
            return nil
        }
    }
    
    func dataToBezier(src: Data) -> UIBezierPath? {
        do {
            return try NSKeyedUnarchiver.unarchivedObject(ofClass: UIBezierPath.self, from: src)!
        } catch {
            return nil
        }
    }

这似乎是 Apple 强加的多项更改。我的需求很简单,而且我正在做的事情很完美,但我当然不想遇到未来的问题。

这个答案:'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release 适用于可存储为可变形的对象,我无法正常工作。同样,这里的建议是使用 Data 并且效果很好。

我已经在这里和其他地方阅读了所有我能找到的答案,因为基本上,StackOverflow 通常会优先考虑在提出问题后立即接受的答案,并且当接受的答案过时时没有更新方法......它可以是在获得相关答案时,这是一个燃烧的混乱垃圾箱,至少对于像 moi 这样的相对新手而言。

但我离题了。谁能指出我当前的做法,让我可以简单地将 UIBezierPaths 序列化和反序列化到 CoreData 存储中?

【问题讨论】:

标签: swift core-data uibezierpath archiving


【解决方案1】:

我已经尝试过了,它成功地进行了编码和解码。没有关于过时函数的警告。

这应该适用于Binary Data

func bezierToData(path: UIBezierPath) -> Data? {
    try? NSKeyedArchiver.archivedData(withRootObject: path, requiringSecureCoding: true)
}

func dataToBezier(src: Data) -> UIBezierPath? {
    try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(src) as? UIBezierPath
}


let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 100, height: 200), cornerRadius: 10)
let pathData = bezierToData(path: path)

let unarchivedPath = dataToBezier(src: pathData!)

另一种选择是创建Transformable 字段和NSSecureUnarchiveFromDataTransformer 以在其中使用。不要忘记在 CoreData 数据模型检查器中设置此 Transformer(并将 Custom class 设置为 UIBeizerPath)。

import UIKit

class UIBezierPathToDataTransformer: NSSecureUnarchiveFromDataTransformer {
    override class func allowsReverseTransformation() -> Bool {
        return true
    }
    override class func transformedValueClass() -> AnyClass {
        return UIBezierPath.self
    }
    override class var allowedTopLevelClasses: [AnyClass] {
        return [UIBezierPath.self]
    }
    override func transformedValue(_ value: Any?) -> Any? {
        guard let data = value as? Data else {
            fatalError("Wrong data type: value must be a Data object; received \(type(of: value))")
        }
        return super.transformedValue(data)
    }
    override func reverseTransformedValue(_ value: Any?) -> Any? {
        guard let path = value as? UIBezierPath else {
            fatalError("Wrong data type: value must be a UIBezierPath object; received \(type(of: value))")
        }
        return super.reverseTransformedValue(path)
    }
}

extension NSValueTransformerName {
    static let uiBezierPathToDataTransformer = NSValueTransformerName(rawValue: "UIBezierPathDataTransformer")
}

当将它添加到您创建持久容器的位置时(可能在 AppDelegate 中):

lazy var persistentContainer: NSPersistentContainer = {
    // Register the transformer at the very beginning.
 ValueTransformer.setValueTransformer(UIBezierPathToDataTransformer(), forName: .uiBezierPathToDataTransformer) // <- HERE

let container = NSPersistentContainer(name: "CoreDataAttributes")
container.loadPersistentStores(completionHandler: { (_, error) in
    guard let error = error as NSError? else { return }
    fatalError("###\(#function): Failed to load persistent stores:\(error)")
})
  
container.viewContext.automaticallyMergesChangesFromParent = true
SampleData.generateSampleDataIfNeeded(context: container.newBackgroundContext())

return container
}()

【讨论】:

  • 感谢您提供详尽的答案,...将对此进行尝试。
猜你喜欢
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多