#swift #codable #cashapelayer #nscoding #decodable
#swift #кодируемый #cashapelayer #nscoding #декодируемый
Вопрос:
Я пытаюсь сохранить и получить информацию о CAShapeLayers в файлах .json, используя Codable протокол, но получаю ошибку:
public class Node: Codable {
public var name: String = ""
public var path: CGPath?
public var baseLayer: CAShapeLayer?
public required init(from decoder: Decoder) throws {
let container = try? decoder.container(keyedBy: NodeCodingKeys.self)
let _name = try container?.decodeIfPresent(String.self, forKey: NodeCodingKeys.name)
let _baseLayer = try container?.decodeIfPresent(CAShapeLayer.self, forKey: NodeCodingKeys.baseLayer)
name = _name ?? ""
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: NodeCodingKeys.self)
try container.encode(name, forKey: NodeCodingKeys.name)
}
}
public enum NodeCodingKeys: CodingKey {
case path
case name
case baseLayer
}
И то же самое для CGPath. Есть ли какой-либо способ сохранить / получить их на / с устройства?
Ответ №1:
Я не смог найти способ сделать CAShapeLayer
соответствие Codable
, поэтому я создал класс для своего объекта данных:
public class ImageNode: NSObject, NSCoding, NSSecureCoding {
public static var supportsSecureCoding = true
var name: NSString
var baseLayer: CAShapeLayer
init(name: NSString,
baseLayer: CAShapeLayer
) {
self.name = name
self.baseLayer = baseLayer
}
public func encode(with coder: NSCoder) {
coder.encode(name, forKey: "name")
coder.encode(baseLayer, forKey: "baseLayer")
}
public required convenience init?(coder: NSCoder) {
guard let name = coder.decodeObject(forKey: "name") as? NSString
else { return nil }
guard let baseLayer = coder.decodeObject(forKey: "baseLayer") as? CAShapeLayer
else { return nil }
print("decode node")
self.init(
name: name,
baseLayer: baseLayer
)
} }
который хорошо работает с NSKeyedArchiver
NSKeyedUnarchiver
сохранением данных в файл и для их извлечения. Может быть, это решение кому-то поможет.