приведите CAShapeLayer и CGPath в соответствие с Codable или NSCoding

#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 сохранением данных в файл и для их извлечения. Может быть, это решение кому-то поможет.