UserDefaults:存储小型数据
存储的内容超过2M,启动速度将会极慢。
只能存储基础数据类型,如字典,数组,浮点数,整型,字符串等。不能存高级数据类型,如类,结构体等。
这里以存储聊天记录举例,实际开发中不能用来存储这么大的。
思路:
将Model中聊天记录转换为字典形式的数组,存进UserDefaults中,要加载聊天记录的时候,再从UserDefaults中提取,将其传入Model中。
- 用一个方法
save将消息以字典形式,根据chatID的不同,存进UserDefaults中。 - 为存进UserDefaults做准备,用一个方法
toDic将存储信息的Model转成字典形式,所以这个函数返回的是一个字典。 - 用一个方法
toChatModel加载聊天消息。要传字典进去才能转成聊天信息,所以参数为字典,返回的是将字典传进去了的model。 - 用一个方法
getAllMsg从UsersDefaults中根据chatID提取存储聊天信息的字典,并用方法toChatModel将其转为Model,加载聊天记录。
用一个方法save将消息以字典形式,根据chatID的不同,存进UserDefaults中。
swift
func save() {
}
为存进UserDefaults做准备,用一个方法toDic将存储信息的Model转成字典形式,所以这个函数返回的是一个字典。
为存进UserDefaults做准备,将存储信息的Model转成字典形式,所以这个函数返回的是一个字典
swift
func toDic() -> [String: Any] {
var muDic: [String: Any] = [:]
//先定义一个空字典
//往里面传Model,让Model的值被传到字典内.发送的信息也是从Model里来的
muDic["chatID"] = chatID
muDic["messageID"] = messageID
muDic["content"] = content
muDic["target"] = target
muDic["mineHead"] = mineHead
muDic["otherHead"] = otherHead
muDic["type"] = type
muDic["filePath"] = filePath
muDic["address"] = address
muDic["latitude"] = latitude
muDic["longitude"] = longitude
return muDic
}
[String: Any]是一个字典数组,这是一个数组,里面储存的是字典类型的元素。
字典的形式就是(键): (值)
用一个方法toChatModel加载聊天消息。要传字典进去才能转成聊天信息,所以参数为字典,返回的是将字典传进去了的model。
将存储的字典转换为Model,因为我们在调用的时候还没有可用的实例。所以我们用static来调用该类型方法。
要传字典进去才能转,所以参数为字典,返回的是将字典传进去了的model。
swift
static func toChatModel(dic: [String: Any]) -> ChatTextModel {
let chatID: String = dic["chatID"] as? String ?? ""
let messageID: String = dic["messageID"] as? String ?? ""
let content: String = dic["content"] as? String ?? ""
let target: String = dic["target"] as? String ?? ""
let mineHead: String = dic["mineHead"] as? String ?? ""
let otherHead: String = dic["otherHead"] as? String ?? ""
let type: String = dic["type"] as? String ?? ""
let filePath: String = dic["filePath"] as? String ?? ""
let address: String = dic["address"] as? String ?? ""
let latitude: Double = dic["latitude"] as? Double ?? 0.0
let longitude: Double = dic["longitude"] as? Double ?? 0.0
return ChatTextModel(chatID: chatID, messageID: messageID, content: content, target: target, mineHead: mineHead, otherHead: otherHead, type: type, filePath: filePath, address: address, latitude: latitude, longitude: longitude)
}
用一个方法getAllMsg从UsersDefaults中根据chatID提取存储聊天信息的字典,并用方法toChatModel将其转为Model,加载聊天记录。
从UsersDefaults中提取已存储的字典,并将其转为Model,为重进的时候加载聊天记录用。
将存储的字典转换为Model,因为我们在调用的时候还没有可用的实例。所以我们用static来调用该类型方法。
swift
static func getAllMsg(chatID: String) -> [ChatTextModel] {
//根据chatID提取到信息,就转为传进Model
if var msgs = UserDefaults.standard.object(forKey: chatID) as? [[String: Any]] {
//如果有信息,就对里面的每个信息都进行转换成Model的操作
return msgs.map { dic in
ChatTextModel.toChatModel(dic: dic)
//.map表示对msgs中的每个元素进行操作,.map常用于遍历数组中的全部元素,并在执行一些操作后返回它们。
}
} else {
return[]
//如果没有信息,就返回空
}
}
返回写存储函数save,因为要在没实例的时候调用,也加static
swift
func save() {
if var msgs = UserDefaults.standard.object(forKey: chatID) as? [[String: Any]] {
msgs.append((toDic()))
UserDefaults.standard.set(msgs, forKey: self.chatID)
print("成功将消息存到老字典")
} else {
UserDefaults.standard.set([toDic()], forKey: self.chatID)
print("成功创建新字典并将消息存到UserDefaults")
}
}
第一次发消息的时候走的是else部分,因为UserDefaults里还没有存任何字典,所以要根据发送的信息(这是一个Model的形式),把消息转成字典,并存进UserDefaults里。
第二次在同一个聊天窗发消息走的就是if var部分了,因为已经UserDefault里已经有东西了,将它转换为字典数组形式,然后再添加新转换的字典元素进(UserDefault中的数组中)。
else部分:
- 如果
UserDefaults里没存消息,说明没有找到与 chatID 相关的消息记录。 - 使用
UserDefaults.standard.set方法将新的字典消息放入一个数组中,并用 chatID 作为键(key)保存到UserDefaults。
if var部分:
-
检查是否已经存在存储的消息记录:
UserDefaults.standard.object(forKey: chatID)试图获取存储的对象,并使用as? [[String: Any]]转换为字典数组(即[[String: Any]])→所以msgs是一个字典数组。如果存在,将新消息追加到这些记录中。
.append方法把新的消息记录追加到之前取出的消息数组里。 -
使用
UserDefaults.standard.set方法将新的字典消息放入一个数组中,并用 chatID 作为键(key)保存到 UserDefaults。
set([toDic()], forKey: self.chatID)意味着创建一个新的消息数组,并将它保存
将加载聊天记录获得的新的Model部分传进ChatViewController中的chatModels中,同样是根据chatID传入。
swift
chatModels.append(contentsOf: ChatTextModel.getAllMsg(chatID: messCellmodel.chatID))
在每次发送消息的时候,调用save函数,将信息以字典数组形式保存到UserDefaults中
swift
newmodel.save()
发送消息的地方都要添加。这样就可以实现将消息存在UserDefaults里。