ios UIColor可以在SwiftData中持久化吗

tpxzln5u  于 11个月前  发布在  iOS
关注(0)|答案(1)|浏览(99)

我试图通过SwiftData持久化一个包含UIColor类型属性的数据模型。我遵循[教程][1]使用@Attribute(.transformable(by: UIColorValueTransformer.self)) var tileColor: UIColor?声明并实现了UIColorValueTransformer' which subclasses 'ValueTransformer。完整代码如下所示。
然而,Xcode抛出了一个运行时异常,错误消息为“SwiftData/SchemaCoreData.swift:244:Fatal error:Unable to initialize ValueTransformer for UIColorValueTransformer”。我不知道如何通过SwiftData持久化像UIColorColor这样的复杂模型。

// Tile.swift
import SwiftData
import UIKit

@Model
final class Tile {
    @Attribute (.unique) var name: String
    var type: String
    var @Attribute(.transformable(by: UIColorValueTransformer.self)) var tileColor: UIColor?

    init(name: String, type: String, tileColor: UIColor) {
        self.name = name
        self.type = type
        self.tileColor = tileColor
    }
}

final class UIColorValueTransformer: ValueTransformer {

    override class func transformedValueClass() -> AnyClass {
        return UIColor.self
    }

    // return data
    override func transformedValue(_ value: Any?) -> Any? {
        guard let color = value as? UIColor else { return nil }
        do {
            let data = try NSKeyedArchiver.archivedData(withRootObject: color, requiringSecureCoding: true)
            return data
        } catch {
            return nil
        }
    }

    // return UIColor
    override func reverseTransformedValue(_ value: Any?) -> Any? {
        guard let data = value as? Data else { return nil }
    
        do {
            let color = try NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: data)
            return color
        } catch {
            return nil
        }
    }
}

// TileApp.swift
import SwiftUI
import SwiftData

@main
struct TileApp: App {

    init() {
        ValueTransformer.setValueTransformer(UIColorValueTransformer(), forName: NSValueTransformerName("UIColorValueTransformer"))
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .modelContainer(for: [Tile.self])
        }
    }
}

字符串
非常感谢您的帮助[1]:https://azamsharp.com/2023/07/04/the-ultimate-swift-data-guide.html

56lgkhnf

56lgkhnf1#

正如上面@Bram所建议的,解决方案如下:

// Tile.swift
import SwiftData
import UIKit

@Model
final class Tile {
    @Attribute (.unique) var name: String
    var type: String
    var @Attribute(.transformable(by: UIColorValueTransformer.self)) var tileColor: UIColor?

    init(name: String, type: String, tileColor: UIColor) {
        self.name = name
        self.type = type
        self.tileColor = tileColor
    }
}

@objc(UIColorValueTransformer) // The solution is adding this line
final class UIColorValueTransformer: ValueTransformer {

    override class func transformedValueClass() -> AnyClass {
        return UIColor.self
    }

    // return data
    override func transformedValue(_ value: Any?) -> Any? {
        guard let color = value as? UIColor else { return nil }
        do {
            let data = try NSKeyedArchiver.archivedData(withRootObject: color, requiringSecureCoding: true)
            return data
        } catch {
            return nil
        }
    }

    // return UIColor
    override func reverseTransformedValue(_ value: Any?) -> Any? {
        guard let data = value as? Data else { return nil }
    
        do {
            let color = try NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: data)
            return color
        } catch {
            return nil
        }
    }
}

// TileApp.swift
import SwiftUI
import SwiftData

@main
struct TileApp: App {

    init() {
        ValueTransformer.setValueTransformer(UIColorValueTransformer(), forName: NSValueTransformerName("UIColorValueTransformer"))
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .modelContainer(for: [Tile.self])
        }
    }
}

字符串

相关问题