美文网首页
swift JSON转Model 模型优化

swift JSON转Model 模型优化

作者: 丢了理想 | 来源:发表于2018-11-05 14:29 被阅读0次

    标准模型

    struct Model:Codable {
        let id:Int
        let avatar:URL
        let nickname:String
        let publish:TimeInterval
    }
    //解析数据
            do {
               model = try JSONDecoder().decode(Model.self, from: data!)
            } catch  {
                    print(error)
            }
    
    //归档保存数据
                do {
                    let data = try JSONEncoder().encode(model)
                    try data.write(to: path, options: Data.WritingOptions.fileProtectionMask)
                } catch  {
                    print(error)
                }
    //解档
                do {
                    let data = try Data.init(contentsOf: path)
                    let model = try JSONDecoder().decode(Model.self, from: data!)
                } catch  {
                    print(error)
                }
    
    
    
    

    因为有时后台给的字段与客户端不匹配或者字段会变
    如:nickname nickName
    现在优化模型字段

    struct Model:Codable {
        let id:Int
        let avatar:URL
        let nickname:String
        let publishTime:TimeInterval
        enum CodingKeys: String, CodingKey {
            case id, avatar, nickname, nickName
            case publishTime = "publish"
        }
        init(from decoder: Decoder) throws {
              let container = try decoder.container(keyedBy: CodingKeys.self)
              id = try container.decodeIfPresent(Int.self, forKey: .words)
              //其他的也要补齐
              nickname = try container.decodeIfPresent(String.self, forKey: .nickname)
              if nickname == nil{
              nickname = try container.decodeIfPresent(String.self, forKey: .niceName)
              }
        }
    }
    

    因为模型里是时间戳,如果需要转换为时间字符串
    而且有的模型需要进行Array index索引,所以要继承Equatable协议

    enum EnumType:String,Codable {
        case H5 = "H5"
        case APP = "APP"
    }
    struct Model:Codable,Equatable{
        let id:Int
        let avatar:URL
        let type: EnumType
        let nickname:String
        private let publishTime:TimeInterval//如果不使用可以私有
        var publishTimeString: String{
            get{
                let date = Date.init(timeIntervalSince1970: publishTime/1000)
                let formatter = DateFormatter()
                formatter.dateFormat = "MM-dd HH:mm"
                return formatter.string(from: date)
            }
        }
        enum CodingKeys: String, CodingKey {
            case id, avatar, nickname
            case publishTime = "publish"
        }
    }
    

    上面的代码有一个问题,如果产品更新,枚举类型变多了,不更新会报错
    所以我们要重写 Codable协议

    enum EnumType:String,Codable {
        case H5 = "H5"
        case APP = "APP"
        case `defult`
        init(from decoder: Decoder) throws {
              let container = try decoder.singleValueContainer()
              //这里只是一个样例,具体解析可以写的更完善
              self = EnumType(rawValue: try container.decode(String.self)) ?? . defult
        }
    /***
        init(from decoder: Decoder) throws {
            do {
                let container = try decoder.singleValueContainer()
                let rawValue = try container.decode(String.self)
                self = EnumType(rawValue: rawValue) ?? . defult
            } catch  {
                throw error
            }
        }
    ***/
    }
    struct Model:Codable,Equatable{
        let id:Int
        let avatar:URL
        let type: EnumType
        let nickname:String
        private let publishTime:TimeInterval//如果不使用可以私有
        var publishTimeString: String{
            get{
                let date = Date.init(timeIntervalSince1970: publishTime/1000)
                let formatter = DateFormatter()
                formatter.dateFormat = "MM-dd HH:mm"
                return formatter.string(from: date)
            }
        }
        enum CodingKeys: String, CodingKey {
            case id, avatar, nickname, niceName//let不添加niceName
            case publishTime = "publish"
        }
        init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
          id = try container.decodeIfPresent(Int.self, forKey: .words)
          //其他的也要补齐
          nickname = try container.decodeIfPresent(String.self, forKey: . nickname)
          if nickname == nil{
          nickname = try container.decodeIfPresent(String.self, forKey: . niceName)
          }
        }
    }
    

    使用经历
    因为模型是一步一步优化过来的,所以尝试过其他方案
    比如 lazy ,但是struct用lazy在使用的时候会报错,需要用muting func去实现,有一点麻烦
    有的时候只需要修改一个数据名称,CodingKeys需要全部写,xcode没有自动生成

    相关文章

      网友评论

          本文标题:swift JSON转Model 模型优化

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