美文网首页
Swift 4.0 Codable

Swift 4.0 Codable

作者: jsone | 来源:发表于2020-03-13 11:30 被阅读0次

    一、简介

    我们可以使用NSCoderCodable协议来持久化数据,并使用NSKeyedArchiver来持久化/保存,以及使用NSKeyedUnarchiver来分别从用户文档目录获取数据。但是使用NSCoder实现编码和解码需要你的类继承NSObject类并实现NSCoding协议,然而结构体就没办法继承NSObject类,并且NSCoding没有提供错误处理机制。于是从Swift4,Xcode 9,iOS 11开始,可以使用Encodable&Decodable,合并后的Codable来解决这些问题。

    1. Encodable用于编码
    2. Decodable用于解码
    3. Codable包含编码和解码

    Codable不仅支持类而且支持结构体和枚举

    二、实现步骤

    1. 创建一个模型类,并遵守Codable协议
    class ProductModel: Codable {
        open var name: String = ""// 商品名称
        open var price: Double = 0.0// 价格 单位:元
        open var number: NSInteger = 0// 数量
        open var shelfLife: NSInteger = 0// 保质期 单位:天
        open var remainingDays: NSInteger = 0// 剩余天数 单位:天
        open var productionDate: String = ""// 生产日期 格式:yyyy-MM-dd HH:mm:ss
        open var deadlineDate: String = ""// 截止日期 格式:yyyy-MM-dd HH:mm:ss
        static var filePath: String {
            let manager = FileManager.default
            let url = manager.urls(for: .documentDirectory, in: .userDomainMask).first
            print("this is the url path in the documentDirectory \(String(describing: url))")
            return (url?.appendingPathComponent("Data").path)!
        }
        
        init(name: String, price: Double, number: NSInteger, shelfLife: NSInteger, remainingDays: NSInteger, productionDate: String, deadlineDate: String) {
            self.name = name
            self.price = price
            self.number = number
            self.shelfLife = shelfLife
            self.remainingDays = remainingDays
            self.productionDate = productionDate
            self.deadlineDate = deadlineDate
        }
    }
    
    1. 声明CodingKeys枚举
    private enum CodingKeys: String, CodingKey {
        case name
        case price
        case number
        case shelfLife
        case remainingDays
        case productionDate
        case deadlineDate
    }
    
    1. 实现Codable协议的归档和解档方法
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        price = try container.decode(Double.self, forKey: .price)
        number = try container.decode(NSInteger.self, forKey: .number)
        shelfLife = try container.decode(NSInteger.self, forKey: .shelfLife)
        remainingDays = try container.decode(NSInteger.self, forKey: .remainingDays)
        productionDate = try container.decode(String.self, forKey: .productionDate)
        deadlineDate = try container.decode(String.self, forKey: .deadlineDate)
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        try container.encode(price, forKey: .price)
        try container.encode(number, forKey: .number)
        try container.encode(shelfLife, forKey: .shelfLife)
        try container.encode(remainingDays, forKey: .remainingDays)
        try container.encode(productionDate, forKey: .productionDate)
        try container.encode(deadlineDate, forKey: .deadlineDate)
    }
    
    1. 实现商品数据模型的数组的存储和取出
    // MARK: - Public
    class func storeProducts(products: [ProductModel]) -> Void {
        do {
            let data = try PropertyListEncoder().encode(products)
            let success = NSKeyedArchiver.archiveRootObject(data, toFile: filePath)
            print(success ? "Successful save" : "Save failed")
        } catch {
            print("Save failed")
        }
    }
    
    class func retrieveProducts() -> [ProductModel]? {
        guard let data = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as? Data else {
            return nil
        }
        do {
            let products = try PropertyListDecoder().decode([ProductModel].self, from: data)
            return products
        } catch {
            print("Retrieve failed")
            return nil
        }
        
    }
    

    注意:结构体可以在extension中实现协议Codable,而类不行

    参考文章:
    NSKeyedArchiver using Swift 4 Codable protocol
    How to store NSCoding data using Codable
    Swift – NSCoder | Codable | JSONDecoder | JSONEncoder | NSKeyedArchiver | NSKeyedUnarchiver | Serialize | Deserialize | Marshelling | Demarshelling | Parse JSON | Parse Plist

    相关文章

      网友评论

          本文标题:Swift 4.0 Codable

          本文链接:https://www.haomeiwen.com/subject/podmjhtx.html