I got a message in log 'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release. I am not sure how to convert this class to use NSSecureCoding. I am not sure which class is throwing this error. Could you please help me on how to convert this?
I am using requiringSecureCoding: true. Doesn't this make this secure?
class ZoneInfo: NSObject, NSCoding {
var zoneID: CKRecordZone.ID
var serverChangeToken: CKServerChangeToken? = nil
enum CodingKeys: String, CodingKey {
case zoneID
case serverChangeToken
}
func encode(with coder: NSCoder) {
coder.encode(zoneID.encode(), forKey: CodingKeys.zoneID.rawValue)
coder.encode(serverChangeToken?.encode(), forKey: CodingKeys.serverChangeToken.rawValue)
}
required init?(coder: NSCoder) {
self.zoneID = CKRecordZone.ID.decode(coder.decodeObject(forKey: CodingKeys.zoneID.rawValue) as! Data)!
if let tokenData = coder.decodeObject(forKey: CodingKeys.serverChangeToken.rawValue) as? Data {
self.serverChangeToken = CKServerChangeToken.decode(tokenData)
}
}
init(zone: CKRecordZone, serverChangeToken: CKServerChangeToken? = nil) {
self.zoneID = zone.zoneID
self.serverChangeToken = serverChangeToken
}
init(zoneID: CKRecordZone.ID, serverChangeToken: CKServerChangeToken? = nil) {
self.zoneID = zoneID
self.serverChangeToken = serverChangeToken
}
static func decode(_ data: Data) -> ZoneInfo? {
return try? NSKeyedUnarchiver.unarchivedObject(ofClass: ZoneInfo.self, from: data)
}
func encode() -> Data {
return (try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: true)) ?? Data()
}
}
Thanks.
Your
ZoneInfoclass should conform toNSSecureCoding, notNSCoding.Your
encode(with:)is needlessly double-encoding the properties and yourinit?(coder:)is needlessly double-decoding the properties.Here's a corrected version of your class:
Since I can't test this with an actual instance of
CKServerChangeToken, I was only able to verify that the above works with a zoneID. If you have an issue at runtime when you try to unarchive an instance ofZoneInfowith a realCKServerChangeTokenvalue, let me know in a comment what the error is so I can update the answer if needed.Note that the use of
CodingKeysisn't normally used withNSSecureCoding. It's normally used for SwiftCodable. Your use here does work, it's just a bit confusing.I also suggest that your
encodemethod returnData?instead of returning an emptyDatainstance on failure. Returning empty data will just lead to issues when you try to unarchive that empty data.