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 } }