Reputation: 788
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