Hi
I have spent a day not figuring out how can I implement the following:
I wrote a class that contains an int and a string
public class GrammarUnit : NSObject, NSSecureCoding {
public static var supportsSecureCoding: Bool = true
public func encode(with coder: NSCoder) {
coder.encode(body, forKey: Key.body.rawValue)
coder.encode(style, forKey: Key.style.rawValue)
}
public required convenience init?(coder decoder: NSCoder) {
//let mBody = decoder.decodeObject(forKey: Key.body.rawValue) as! String
//let mStyle = decoder.decodeInt64(forKey: Key.style.rawValue)
let mBody = decoder.decodeObject(of: NSString.self, forKey: Key.body.rawValue) as String? ?? ""
let mStyle = decoder.decodeInteger(forKey: Key.style.rawValue)
self.init(body: mBody, style: Int(mStyle))
}
var body : String
var style : Int = 0
enum Key: String, CodingKey {
case body = "body"
case style = "style"
}
init(body: String, style: Int) {
self.body = body
self.style = style
}
}
Then In coreData manager I created an entity as follow:
From what I have searched, it says that I need to create a subClass of transformer and so I did:
@objc(GrammarUnitValueTransformer)
final class GrammarUnitValueTransformer: NSSecureUnarchiveFromDataTransformer {
// The name of the transformer. This is what we will use to register the transformer `ValueTransformer.setValueTrandformer(_"forName:)`.
static let name = NSValueTransformerName(rawValue: String(describing: GrammarUnitValueTransformer.self))
// Our class `Test` should in the allowed class list. (This is what the unarchiver uses to check for the right class)
override static var allowedTopLevelClasses: [AnyClass] {
return [GrammarUnitValueTransformer.self]
}
/// Registers the transformer.
public static func register() {
let transformer = GrammarUnitValueTransformer()
ValueTransformer.setValueTransformer(transformer, forName: name)
}
}
and then I initialized the static register function just before the persistence controller is initialized:
I am testing it by adding an instance:
Button {
let apl = GrammarComponents(context: self.context)
apl.id = UUID().uuidString
apl.components = GrammarUnit(body: "apple", style: 0)
do {
try context.save()
} catch {
print(error.localizedDescription)
}
} label: {
Text("save")
}
but I am receiving error upon executing the save
You might ask why I just don’t put the String and Int as property of that Entity.
Originally, the field was an array, as I need the pair in sequence
I was just testing perhaps that the valueTransformer I created was for single instance
I also make sure I regenerated the CoreData class entity definition before testing
I tried also the solution as suggested here:
I change it to:
public class GrammarUnits: NSObject, NSSecureCoding {
public static var supportsSecureCoding: Bool = true
public var grammarUnits : [GrammarUnit] = []
enum Key:String {
case grammarUnits = "grammarUnits"
}
init(grammarUnits: [GrammarUnit]) {
self.grammarUnits = grammarUnits
}
public func encode(with coder: NSCoder) {
coder.encode(grammarUnits, forKey: Key.grammarUnits.rawValue)
}
public required convenience init?(coder decoder: NSCoder) {
let untis = decoder.decodeObject(of: NSArray.self, forKey: Key.grammarUnits.rawValue) as! [GrammarUnit]
self.init(grammarUnits: untis)
}
}
public class GrammarUnit : NSObject, NSCoding {
public var body : String
public var style : Int = 0
enum Key: String {
case body = "body"
case style = "style"
}
init(body: String, style: Int) {
self.body = body
self.style = style
}
public func encode(with coder: NSCoder) {
coder.encode(body, forKey: Key.body.rawValue)
coder.encode(style, forKey: Key.style.rawValue)
}
public required convenience init?(coder decoder: NSCoder) {
let mBody = decoder.decodeObject(forKey: Key.body.rawValue) as! String
let mStyle = decoder.decodeInteger(forKey: Key.style.rawValue)
self.init(body: mBody, style: Int(mStyle))
}
}
Then for the valueTransformer, I tried both:
return [NSArray.self]
}
override static var allowedTopLevelClasses: [AnyClass] {
return [GrammarUnits]
}
then again I tested, but still I encountering same errors
Please help, Im kinda stuck
Thanks in advance