小编最近在 Swift
项目中遇到这么一个问题,那就是用户在更新后,登录状态丢失了。
关于当前用户数据,我是使用归解档,存储到
Document
文件下的一个plist
文件中。判断登录状态的依据是在App
启动的时候是否可以获取到这个文件中的用户数据。
第一个猜想:plist
文件是不是被删除?
多方考证后确定,覆盖安装是不会删除这个文件的,除非将 App
删除。
第二个猜想:解档失败
一顿
debug
跟踪后,确定是这个问题导致更新后登录状态丢失
在 debug
过程中,在控制台打印如下:
po PropertyListDecoder().decode(User.self, from: data)
▿ DecodingError
▿ keyNotFound : 2 elements
- .0 : CodingKeys(stringValue: "likeFind", intValue: nil)
▿ .1 : Context
- codingPath : 0 elements
- debugDescription : "No value associated with key CodingKeys(stringValue: \"likeFind\", intValue: nil) (\"likeFind\")."
- underlyingError : nil
分析:
likeFind
这个字段是在新的版本添加的字段,在旧版本的原来的plist
文件中没有这个字段,解档的时候直接报错,导致解档失败
解决:由于没有默认值,使用
decoder
方法解档就会报错,使用decodeIfPresent
方法解档就没有问题了。
原来的代码:
class YMLoginModel: YMBaseModel {
...
//用户个人主页新增
var likeFind: String = ""
...
override func mapping(map: Map) {
...
//用户个人主页新增
likeFind <- map["like_find"]
...
}
private enum CodingKeys: String, CodingKey {
...
case likeFind = "likeFind"
...
}
required init(from decoder: Decoder) throws {
super.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
...
likeFind = try container.decode(String.self, forKey: .likeFind)
...
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
...
}
}
没有问题的代码:
class YMLoginModel: YMBaseModel {
...
//用户个人主页新增
var likeFind: String = ""
...
override func mapping(map: Map) {
...
//用户个人主页新增
likeFind <- map["like_find"]
...
}
private enum CodingKeys: String, CodingKey {
...
case likeFind = "likeFind"
...
}
required init(from decoder: Decoder) throws {
super.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
...
likeFind = try container.decodeIfPresent(String.self, forKey: .likeFind) ?? ""
...
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
...
}
}
网友评论