iOS Development

ios – convert NSCoding to NSSecureCoding?

Your ZoneInfo class ought to conform to NSSecureCoding, not NSCoding.

Your encode(with:) is needlessly double-encoding the properties and your init?(coder:) is needlessly double-decoding the properties.

This is a corrected model of your class:

class ZoneInfo: NSObject, NSSecureCoding {
    // Added to assist NSSecureCoding
    static var supportsSecureCoding: Bool { return true }

    var zoneID: CKRecordZone.ID
    var serverChangeToken: CKServerChangeToken? = nil

    enum CodingKeys: String, CodingKey {
        case zoneID
        case serverChangeToken

    // Up to date to keep away from the double-encoding
    func encode(with coder: NSCoder) {
        coder.encode(zoneID, forKey: CodingKeys.zoneID.rawValue)
        coder.encode(serverChangeToken, forKey: CodingKeys.serverChangeToken.rawValue)

    // Up to date to keep away from the double-decoding and to correctly deal with an invalid zoneID
    required init?(coder: NSCoder) {
        if let zoneID = coder.decodeObject(of: CKRecordZone.ID.self, forKey: CodingKeys.zoneID.rawValue) {
            self.zoneID = zoneID
        } else {
            return nil
        self.serverChangeToken = coder.decodeObject(of: CKServerChangeToken.self, forKey: CodingKeys.serverChangeToken.rawValue)

    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(_ knowledge: Knowledge) -> ZoneInfo? {
        return strive? NSKeyedUnarchiver.unarchivedObject(ofClass: ZoneInfo.self, from: knowledge)

    func encode() -> Knowledge {
        return (strive? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: true)) ?? Knowledge()

Since I can not check this with an precise occasion of CKServerChangeToken, I used to be solely in a position to confirm that the above works with a zoneID. You probably have a difficulty at runtime once you attempt to unarchive an occasion of ZoneInfo with an actual CKServerChangeToken worth, let me know in a remark what the error is so I can replace the reply if wanted.

Be aware that using CodingKeys is not usually used with NSSecureCoding. It is usually used for Swift Codable. Your use right here does work, it is only a bit complicated.

I additionally recommend that your encode methodology return Knowledge? as a substitute of returning an empty Knowledge occasion on failure. Returning empty knowledge will simply result in points once you attempt to unarchive that vacant knowledge.


Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button