聊天功能(一)--Message模型
2018-06-05 本文已影响22人
Mage
最近在整理开发聊天功能的代码,将相关代码整理成教程以便理清思路,同时希望能给初学者一些启发.文章采用Swift4.1开发,顺应潮流.
首先创建Message模型,message里应该有基本的comment(内容)、from(来源)、type(类型)、id(消息标示)、timestamp(时间戳).为了使用方便,将type和from设计成enum.代码如下:
Message.swift
public class Message {
public enum FType: Int {
case text
case img
case voice
case system
}
public enum From: Int {
case me
case other
case system
}
public var type: FType
public var comment: String
public var from: From
public var timestamp: TimeInterval
public var id: Int? = -1
public var isShowTime: Bool = false
private static var defaultTime: TimeInterval = 0
private static var defaultTimeIndex: UInt = 0
public init(type: FType, comment: String, from: From, id: Int) {
self.timestamp = Date().timeIntervalSinceReferenceDate
self.isShowTime = { timestamp in // 比上一条增加60s或者已经有10条未显示时间时,可以显示时间
let canShow = timestamp - Message.defaultTime > 60 || Message.defaultTimeIndex > 10
Message.defaultTime = timestamp
Message.defaultTimeIndex = canShow ? 0 : Message.defaultTimeIndex + 1
return canShow
}(self.timestamp)
self.type = type
self.comment = comment
self.from = from
self.id = id
}
}
添加Comparable协议
为了以后使用方便,需要给Message增加一些其他协议,增强功能.
// 在打印时,会直接打印id,避免其他内容干扰
extension Message : CustomStringConvertible {
public var description: String {
return "\(self.id ?? -1)"
}
}
// 支持Comparable,使Message可以比较,对之后Message排序有帮助
extension Message : Comparable, Hashable {
public static func < (lhs: Message, rhs: Message) -> Bool {
if let lhsId = lhs.id, let rhsId = rhs.id {
return lhsId < rhsId
}else{
return lhs.timestamp < rhs.timestamp
}
}
public static func == (lhs: Message, rhs: Message) -> Bool {
if let lhsId = lhs.id, let rhsId = rhs.id {
return lhsId == rhsId
}else{
return lhs.timestamp == rhs.timestamp
}
}
public var hashValue: Int {
if let id = self.id {
return id
}else{
return Int(self.timestamp * 1000000)
}
}
}
randomMessage 随机消息
为了之后使用方便,给Message添加一些随机创建消息的方法.
extension Message {
static var sortIndex: Int = -1
public static func randomMessage()-> Message{
sortIndex = sortIndex + 1
var comment:String! = nil
let from: From! = From.init(rawValue: random(3))
var type: FType! = FType.init(rawValue: random(3))
switch type {
case .text:
comment = randomText()
case .img:
comment = "\(random(12)+1).jpg"
case .voice:
comment = "\(sortIndex)"
default:
break
}
if from == .system {
type = .system
comment = randomSystem()
}
return Message.init(type: type, comment: comment, from: from, id: sortIndex)
}
public static func randomSystem() -> String {
let systems = ["请耐心等待,客服忙",
"客服正在处理您的问题,请稍后",
"服务已断开,请稍后重试",
"服务超时,请关闭对话",
"请耐心等待,客服忙请耐心等待,客服忙请耐心等待,客服忙",
"服务超时,请关闭对话服务超时,请关闭对话服务超时,请关闭对话服务超时,请关闭对话服务超时,请关闭对话服务超时,请关闭对话",
"请耐心等待,客服忙请耐心等待,客服"
]
return systems[random(7)]
}
public static func randomText() -> String{
let text = "如果是原地的话。。。200万年以前的更新世,支撑现在世界上大多数沿海大城市的冲积平原还不存在。所以,鉴于世界人口有一半分布在距离海岸线200公里之内,还有第四纪的冰川啊,河流啊,地面高差不同啊,恐怕大部分人“着陆”的时候就挂了吧。╮( ̄⊿ ̄)╭其实能不能安全落地影响并不大,因为绝大多数现代人会在着陆之后的72小时内死于脱水(干净水源并不是遍地都是啦),肠道疾病(叫你喝生水/乱吃东西),低体温症(在野外露天过夜),还有各种蠢死(拿着削尖的木棍挑战野猪,吃了不认识的果子和蘑菇,走夜路摔,篝火一氧化碳中毒,etc.)相对来说能熬到饿死或者被野兽抓走的反倒是比较成功人士了。然后,估计用不了等到72小时,人群中就会爆发大规模的暴力争斗(抢水抢食物抢妹子聊不到一起去。)。比较恐怖的一点,到了这个节骨眼上,人肉,几乎成了唯一能足量供应的。。。资源了。接下来的几天,在大型人类聚居区周围逐渐堆积的废弃物,包括尸体,吃剩的尸体,排泄物,会迅速腐烂滋生毒气和害虫,铺天盖地的害虫。疫病爆发,主要是霍乱,痢疾等消化道疾病和皮肤感染。然后野生动物开始注意到这些新来的成群的光溜溜的弱鸡。在东亚大陆的朋友们有福气了,会见到由上万头熊猫组成的壮观的“熊猫-剑齿象动物群”。只不过那时候滚滚们还是吃肉的。"
let range = randomRange(text.count)
let start = text.index(text.startIndex, offsetBy: range.0)
let end = text.index(text.startIndex, offsetBy: range.1)
return String(text[start..<end])
}
public static func randomRange(_ count: Int)-> (Int,Int){
let x = random(count)
let y = random(count)
return (min(x, y), max(x, y))
}
public static func random(_ count: Int)-> Int {
return Int(arc4random_uniform(UInt32(count)))
}
}
Demo地址:MAChatTableViewDemo