SwiftData Transformable [String] Object

I'm trying to create a SwiftData object with a [String] property 'cited'. I've written a custom ValueTransformer, but I get fatalError message:

SwiftData/SchemaProperty.swift:1212: Fatal error: Failed to serialize ["32006R0561", "32002L0015", "32014R0165", "62019CJ0906", "32009R1073", "62021CJ0013"] to Data using <MyApp.StringArrayTransformer: 0x3034dc170>

I want to be able to create SwiftData objects with array properties, such as [String] and [Int], and parse them from JSON on the first run.

Here is the model:

@Model
final class MyModel: Hashable, Codable {
var date:           String
var name:           String
@Attribute(.transformable(by: StringArrayTransformer.self)) var cited: [String]

}

init(date: String, name: String, cited: [String]) {
    self.date =             date
    self.name =             name
    self.cited =            cited
    
}

enum CodingKeys: CodingKey {
    case date
    case name
    case cited
   
}
required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)

    self.date =             try container.decode(String.self, forKey: .date)
    self.name =             try container.decode(String.self, forKey: .name)
    self.cited =            try container.decode([String].self, forKey: .cited)
    
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)

    try container.encode(date, forKey: .date)
    try container.encode(name, forKey: .name)
    try container.encode(cited, forKey: .cited)

}

Here is the ValueTransformer:

class StringArrayTransformer: ValueTransformer {
override func transformedValue(_ value: Any?) -> Any? {
    guard let cited = value as? String else { return nil }
    return cited.components(separatedBy: ", ")

}

override func reverseTransformedValue(_ value: Any?) -> Any? {
    guard let strings = value as? [String] else { return nil }
    let string = strings.joined(separator: ", ")
    guard let data = string.data(using: .utf8) else { return nil }
    
    return data

}

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

override class func allowsReverseTransformation() -> Bool {
     return true
}

static func register() {
    ValueTransformer.setValueTransformer(StringArrayTransformer(), forName: .init("StringArrayTransformer"))
}


}

Upvotes: 0

Views: 25

Answers (0)

Related Questions