generi c быстрая сериализация объекта? - PullRequest
0 голосов
/ 08 июля 2020

Есть ли общий c способ сериализации / десериализации объектов для iOS? Я использовал следующий код, и системные функции, которые я вызывал, устарели в iOS 12:

  func object(forKey:String) -> Any? {
    if let data = get(BLOB_COL, forKey) {
      return NSKeyedUnarchiver.unarchiveObject(with: data as! Data)
    }
    return nil
  }

  func set(_ object:Any, forKey: String) {
    let data = NSKeyedArchiver.archivedData(withRootObject: object)
    updateOrInsert(forKey, BLOB_COL, data)
  }

Похоже, что новые версии этих функций требуют знания классов объектов и различных сигнатур для разархивирования различных типов коллекций ... есть ли простой способ справиться с этим в целом?

Ответы [ 2 ]

0 голосов
/ 09 июля 2020

Если вы хотите использовать NSKeyedArchiver / NSKeyedUnarchiver:

При архивировании изменения:

NSKeyedArchiver.archivedData...

на

NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)

И при разархивировании изменения

* От 1010 *

до

NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)

Общий протокол кодирования c подход

Если вы хотите использовать Codable для кодирования и декодирования (сериализации) вашего Data, вы можете расширить протокол Encodable и создать метод для закодировать любой объект, который ему соответствует:

extension Encodable {
    func data(using encoder: JSONEncoder = JSONEncoder()) throws -> Data { try encoder.encode(self) }
}

А для декодирования закодированных данных вы можете расширить Data и создать общий c метод, который декодирует любой объект, соответствующий Decodable:

extension Data {
    func object<T: Decodable>(using decoder: JSONDecoder = JSONDecoder()) throws -> T {
        try decoder.decode(T.self, from: self)
    }
    // you can also create a string property to convert the JSON data to String
    var string: String? { String(data: self, encoding: .utf8) }
}

Использование:

struct Person: Codable {
    let name: String
    let age: Int
}
do {
    // encoding
    let person = Person(name: "Joe", age: 10)
    var people = [Person]()
    people.append(person)
    let data = try people.data()
    print(data.string ?? "")  // [{"name":"Joe","age":10}]
    // decoding
    let loadedPeople: [Person] = try data.object()
    loadedPeople.forEach({print( $0.name, $0.age)})  // Joe 10
} catch {
    print(error)
}
0 голосов
/ 08 июля 2020

Как говорит Лео, прекратите использовать NSKeyedArchiver и используйте протокол Codable. Это современный способ Swifty сериализации / десериализации ваших объектов.

...