NSKeyedUnarchiver возвращает ноль при получении пользовательского класса - PullRequest
2 голосов
/ 07 апреля 2020

В моем контроллере представления у меня есть хранилище пользовательских классов в массиве. Я использовал NSKeyedArchiver для хранения данных, но я использовал устаревшую версию NSKeyedUnarchiver.unarchiveObject(withFile: object.ArchiveURL.path) as? [object].

Теперь я решил обновить ее до: let data = try Data(contentsOf: filePath) let object = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)

Вот моя функция сохранения:

 let data = try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)
 try data.write(to: filePath)

Когда я возвращаю объект из Unarchiver, он возвращает ноль. Я не уверен почему. Это мой пользовательский класс:

class object: NSObject, NSCoding {
   var name: String
   var photo: UIImage

    struct PropertyKey {
        static let name = "name"
        static let photo = "photo"
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.name, forKey: PropertyKey.name)
        aCoder.encode(self.photo, forKey: PropertyKey.photo)
    }

    required convenience init?(coder aDecoder: NSCoder) {
         // The name is required. If we cannot decode a name string, the initializer should     fail.
         guard let name = aDecoder.decodeObject(forKey: PropertyKey.name) as? String else {
             os_log("unable to find name", log: OSLog.default, type: .debug)
             return nil
         }

         guard let photo = aDecoder.decodeObject(forKey: PropertyKey.photo) as? UIImage else  {
              os_log("unable to find photo", log: OSLog.default, type: .debug)
              return nil
         }


        // Must call designated initializer.
        self.init(name: name, photo: photo)
   }

   init?(name: String, photo: UIImage) {
        // Initialize stored properties.
        self.name = name
        self.photo = photo

   }
}

1 Ответ

1 голос
/ 07 апреля 2020

Вы можете использовать этот метод для разархивирования данных. https://developer.apple.com/documentation/foundation/nskeyedunarchiver/2963379-unarchivedobject

NSKeyedUnarchiver.unarchivedObject(ofClasses:from:)

Вы можете написать свой разархивирующий код как:

let data = try Data(contentsOf: filePath)
let object = try NSKeyedUnarchiver.unarchivedObject(ofClasses:[object.self, UIImage.self], from: data)

Надеюсь, это работает.

PS. Один совет о наименовании классов. Они всегда должны начинаться с заглавной буквы.

РЕДАКТИРОВАТЬ: Вы должны добавить UIImage.self также при попытке разархивировать. и вы должны изменить свой архивный метод, как показано ниже.

NSKeyedArchiver.archivedData(withRootObject: data, requiringSecureCoding: true)

При использовании этого метода разархивирования ваша модель также должна соответствовать протоколу NSSecureCoding.

extension object : NSSecureCoding {
    static var supportsSecureCoding: Bool {
       return true
    }
}
...