In general, Objective-C files data via NSCoding, while Swift files data in Codable. But that doesn’t mean they can’t work together. It takes a little bit of work to file NSCoding data in Codable. How to understand?
For example, UIColor and UIImage implement NSCoding but not Codable.
Here we use a simple struct example:
struct Person {
var name: String
var favoriteColor: UIColor
}
Copy the code
How do I make a Person Codable and archive it through JSONEncoder?
We will follow these four steps:
- create
Persion
的extension
And abide by theCodable
agreement - Create a custom
CodingKey
Is used to describe what data will be saved - implementation
init(from:)
Method to convert the raw data toUIColor
type - implementation
encode(to:)
Methods,UIColor
Data to raw data, like thisCodable
You can encode it base-64
First add extension to Persion:
extension Persion: Codable {}Copy the code
After it is added, compilation fails because UIColor does not implement Codable. Let’s move on to the second step: add custom coding keys.
enum CodingKeys: String.CodingKey {
case name
case favoriteColor
}
Copy the code
We need to manually encode and decode by declaring these coding keys.
Implement decoding operation:
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
// Get the original data
let colorData = try container.decode(Data.self, forKey: .favoriteColor)
// Decode
favoriteColor = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(colorData) as? UIColor ?? UIColor.black
}
Copy the code
Implement coding operations:
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
// Convert to raw data
let colorData = try NSKeyedArchiver.archivedData(withRootObject: favoriteColor, requiringSecureCoding: false)
// Encode
try container.encode(colorData, forKey: .favoriteColor)
}
Copy the code
After the above work is done, we can have fun.
let taylor = Person(name: "Swift", favoriteColor: .blue)
let encoder = JSONEncoder(a)do {
let encoded = try encoder.encode(taylor)
let str = String(decoding: encoded, as: UTF8.self)
print(str)
} catch {
print(error.localizedDescription)
}
Copy the code
原文阅读:How to store NSCoding data using Codable