无法获取 SwiftData 来存储/检索 CGPoint、CGSize、CGRect

问题描述 投票:0回答:1

我试图让 SwiftData 存储 Core Graphics 基本结构,如 CGSize、CGRect、CGPoint,但它不起作用。我想 CGVector 和 CGAffineTransform 可以添加到列表中,但我还没有尝试过。

我的问题:制作 SwiftData 存储/检索 CG 结构的明智方法是什么?

这是我发现的: 所有 CG 结构通过符合 Encodable 和 Decodable 来符合 Codable。然而,它们都使用无密钥编码。未加密的编码将得到下面的简单类,从而导致崩溃

Fatal error: Composite Coder only supports Keyed Container

@Model
class TestCGSize {
    // Fatal error: Composite Coder only supports Keyed Container
    var cgSize: CGSize = CGSize.zero

    init(cgSize: CGSize) { self.cgSize = cgSize }
}

旁注:致命错误消息并不完全正确,因为 CGFloat 可以工作并且 CGFloat 使用无密钥编码。

问题如何解决?

为 Codable 编写扩展: 无法使用新扩展覆盖 Encodable/Decodable 的现有实现。

编写子类:无法对结构进行子类化。

写一个@propertyWrapper:会产生编译错误:

Property wrapper cannot be applied to a computed property
。看来 SwiftData 将所有属性都变成了计算属性。

使用didSet观察者:它确实有效,但只是单向的。 SwiftData 将在数据库中创建列并存储值,但我只能部分检索。请参阅下面的测试代码。

编写一个包装器结构:从我的第一次尝试开始。任何可行的例子都将受到高度赞赏。

可能还有另一种我没有想到的方法。我将不胜感激任何帮助。

@Model
class TestCGSize {
    @Transient
    var cgSize: CGSize = CGSize.zero {
        didSet {
            cgSizeWidth = cgSize.width
            cgSizeHeight = cgSize.height
        }
    }
    
    // Columns created and data stored in db.
    // Data retrieved, but cgSize not updated
    var cgSizeWidth: Double = 0 {
        didSet { cgSize.width = cgSizeWidth }
    }
    var cgSizeHeight: Double = 0 {
        willSet { cgSize.height = newValue }
    }
    
    init(cgSizeWidth: Double, cgSizeHeight: Double) {
        self.cgSizeWidth = cgSizeWidth
        self.cgSizeHeight = cgSizeHeight
        self.cgSize.width = cgSizeWidth
        self.cgSize.height = cgSizeHeight
    }
}
ios swift codable swift-data
1个回答
0
投票

@Transient
创造了第二个真相来源。您可以通过将
cgSize
转换为具有
get
set
的计算属性来保持单一事实来源。

然后为了连续性,您可以设置数据库属性

private

import SwiftData
@Model
class TestCGSize {
    var cgSize: CGSize {
        get {
            .init(width: _cgSizeWidth, height: _cgSizeHeight)
        }
        set {
            self._cgSizeWidth = newValue.width
            self._cgSizeHeight = newValue.height
        }
    }
    
    // Columns created and data stored in db.
    private var _cgSizeWidth: Double = 0.0
    private var _cgSizeHeight: Double = 0.0
    
    init(cgSize: CGSize) {
        self.cgSize = cgSize
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.