When I run my app, Core Data gives this message
[general] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSString' (0x1dcf177d0) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set: '{(
"'NSArray' (0x1dcf0cac8) [/System/Library/Frameworks/CoreFoundation.framework]"
)}'. This will be disallowed in the future.
despite the fact that the custom value transformer that I have specifically allows StoredRoutes
(custom type conforming to NSSecureCoding
), NSArray
and NSString
.
The StoredRoutes
type has an array of an enumeration Route
which I use to keep track of the routes that are served by a station.
What am I missing here?
Value transformer code for reference:
import Foundation
final class StoredRoutesValueTransformer: NSSecureUnarchiveFromDataTransformer {
static var name = NSValueTransformerName(rawValue: "StoredRoutesValueTransformer")
override class func allowsReverseTransformation() -> Bool {
return true
}
override class func transformedValueClass() -> AnyClass {
return StoredRoutes.self
}
override class var allowedTopLevelClasses: [AnyClass] {
return [StoredRoutes.self, NSArray.self, NSString.self]
}
override func transformedValue(_ value: Any?) -> Any? {
guard let data = value as? Data else {
fatalError("Wrong data type: value must be of type Data. The type the value recieved was \(type(of: value)).")
}
return super.transformedValue(data)
}
override func reverseTransformedValue(_ value: Any?) -> Any? {
guard let storedRoutes = value as? StoredRoutes else {
fatalError("Wrong data type: value must be of type StoredRoutes. The type of the value recieved was \(type(of: value))")
}
return super.reverseTransformedValue(storedRoutes)
}
public static func register() {
let transformer = StoredRoutesValueTransformer()
ValueTransformer.setValueTransformer(transformer, forName: name)
}
}
Update: This error occurred since the custom class StoredRoutes
was trying to decode an NSArray, use the methods for decoding an array instead.
Older code:
public init?(coder: NSCoder) {
if let nsArray = coder.decodeObject(of: NSArray.self, forKey: "routes") {
self.routes = []
for id in nsArray {
self.routes.append(Route(rawValue: id as! String)!)
}
} else {
return nil
}
}
New code that fixes this issue:
public init?(coder: NSCoder) {
if let nsArray = coder.decodeArrayOfObjects(ofClass: NSString.self, forKey: "routes") {
self.routes = []
for id in nsArray {
self.routes.append(Route(rawValue: id as String)!)
}
} else {
return nil
}
}