swift——從零開始自己的IM

之前舊項目里的聊天是集成的融云,然而有諸多不方便在张,很多需求都無法正常且簡單的實現(xiàn)用含。而且使用聊天的人也并不多。帮匾。啄骇。

所以決定公司自己開發(fā)即時通訊(反正用戶少=。=)

開發(fā)中是基于Socket.IO封裝使用瘟斜,寫這篇文章時版本是13.0.0缸夹。后臺是Node.js。這是Github地址Socket.IO-Client-Swift

切記螺句!好的產(chǎn)品就別指望了虽惭!多和后臺的大兄弟交流,一定得有討論連接蛇尚,用戶認(rèn)證和消息文本格式的思維芽唇。

先上一個簡單的思維導(dǎo)圖

思維導(dǎo)圖.png

自己補(bǔ)的,大概就是這么個流程取劫。

下面開始上代碼4殷浴(去除掉需求邏輯)

//連接狀態(tài)enum linkState: String {caseno_connection ="未連接"casein_connection ="連接中"caseconnected ="已連接"caseconnection_error ="連接錯誤"}classBSIM{/// 靜態(tài)變量(常量)? static 修飾的靜態(tài)方法不能被重寫staticlet shared = BSIM()varmanager:SocketManager?varsocket:SocketIOClient?varonlineTimer:Timer?varonlineTimerNum =30;/*后臺狀態(tài)保活*/let app = UIApplication.sharedvartaskID = UIBackgroundTaskIdentifier()varbackTimer:Timer?varbackTime =0;//APP進(jìn)入后臺逼仔埃活時間varbackTimeOut =60*3;// MARK:- 初始連接并進(jìn)行認(rèn)證func initAndConnect(server:String,userid:String,random:String,result:@escaping BSIMConnectResult){/// 一些判斷 例如guard server !=""else{self.connectResult!(-9999,"服務(wù)器地址不能為空")return}/// 連接? 第一步的HTTP請求? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /// 打印調(diào)試信息? ? 使用websocketsself.manager = SocketManager(socketURL: URL(string:self.server)!, config: [.log(false), .forceWebsockets(true)])self.socket =self.manager?.defaultSocket/// 監(jiān)聽事件self.socket?.on("你和后臺約定好的字段", callback: { (data, ack) in/// 記得移除? 避免重復(fù)監(jiān)聽self.socket?.off("某些監(jiān)聽")/// 初始化定時器 心跳包if(self.onlineTimer == nil){self.onlineTimer = Timer.scheduledTimer(timeInterval: TimeInterval(self.onlineTimerNum),target:self,selector:#selector(self.onlineTimerRun),userInfo:nil,repeats:true)}else{self.onlineTimer?.invalidate()self.onlineTimer = nilself.onlineTimer = Timer.scheduledTimer(timeInterval: TimeInterval(self.onlineTimerNum),target:self,selector:#selector(self.onlineTimerRun),userInfo:nil,repeats:true)}/// 更改連接狀態(tài)self.linkStatePush(state: linkState.connected)/*

? ? ? ? ? 有關(guān)認(rèn)證的邏輯代碼

? ? ? ? ? *//// 基本設(shè)置self.completion()? ? ? ? })? ? ? ? }/// 初始化設(shè)置privatefunc completion(){/// 移除自身通知NotificationCenter.default.removeObserver(self)//注冊進(jìn)入后臺通知NotificationCenter.default.addObserver(self, selector:#selector(self.EnterBackgroundNotification), name:NSNotification.Name.UIApplicationDidEnterBackground, object: nil)//注冊進(jìn)入前臺通知NotificationCenter.default.addObserver(self, selector:#selector(self.EnterForegroundNotification), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)self.onMessage(MsgAction:"message") { (dataString) in? ? ? ? ? ? ? ? ? ? ? ? let data = dataString.data(using: String.Encoding.utf8)? ? ? ? ? ? let js = JSON(data:data!)/// 自定義的Modellet msgModel = MsgBaseModel.init()/// 收到數(shù)據(jù)ifjs["msgId"].stringValue !=""{/*

? ? ? ? ? ? ? ? 解析數(shù)據(jù)

? ? ? ? ? ? ? ? 數(shù)據(jù)解析用的SwiftyJSON

? ? ? ? ? ? ? ? 本地數(shù)據(jù)存儲用的FMDB

? ? ? ? ? ? ? ? *///聲音提醒self.applicationState(pushData: ((js["sendName"].stringValue) ==""? (js["pushData"].stringValue) : (js["sendName"].stringValue) +": "+ (js["pushData"].stringValue)))if(self.checkedMessage(MsgId: msgModel.msgId)){print("\(msgModel.msgId) 消息數(shù)據(jù)庫中已存在")return}? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? let ins =self.insertMsg(model: msgModel)if(ins ==false){print("\(msgModel.msgId) 消息插入失敗")return}/// 通知 更新UI界面self.SessionListNotice?.newMessage(MsgModel: msgModel)self.SessionNotice?.newMessage(MsgModel: msgModel)/// 未讀消息條數(shù)let arr =self.getSessionListData()varnumber =0formodel in arr{? ? ? ? ? ? ? ? ? ? number = number + model.notReadNumber? ? ? ? ? ? ? ? ? ? let na = NSNotification.Name(rawValue:"news")? ? ? ? ? ? ? ? ? ? NotificationCenter.default.post(name: na, object:(number))? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? ? ? ? ? }/// 監(jiān)聽消息privatefunc onMessage(MsgAction:String,cb:@escaping (_ data:String)->Void){self.socket?.on(MsgAction, callback: { (data, ack) in/// 在TCP/IP協(xié)議中炮捧,如果接收方成功的接收到數(shù)據(jù),那么會回復(fù)一個ACK數(shù)據(jù)ack.with(UUID().uuidString)ifdata[0] is String{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cb(data[0]as? String ??"")? ? ? ? ? ? ? ? ? ? ? ? ? ? }else{//此處后期可能語音圖片等格式文件需要做相應(yīng)判斷cb(bs_String.objectToJson(object: (data[0]as? Dictionary) ?? [:]) ??"")? ? ? ? ? ? }? ? ? ? })? ? }? ? ? ? @objc func EnterForegroundNotification(){print("進(jìn)入前臺")if(self.backTime {/// 邏輯代碼}? ? ? ? })? ? } }

以上代碼差不多是連接惦银,設(shè)置(心跳包咆课,通知等)末誓,收到消息(處理數(shù)據(jù),更新UI)等一系列方法的去邏輯版傀蚌。本地數(shù)據(jù)存儲也就是檢查下有沒有重復(fù)基显,不存在就插入。

這樣就基本實現(xiàn)了用戶登錄善炫,可以接收到產(chǎn)品想要的自定義消息撩幽,比如系統(tǒng)消息,賬單消息等等箩艺。但是如果需要單聊窜醉,你就需要根據(jù)用戶id取聊天數(shù)據(jù),然后條數(shù)多了肯定需要分頁艺谆。所以要多一個getUserMsgListPageData(userid:String, page:Int)這種方法榨惰。

然后消息主頁,子界面的那些處理就需要自己去慢慢拓展了静汤。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琅催,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子虫给,更是在濱河造成了極大的恐慌藤抡,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抹估,死亡現(xiàn)場離奇詭異缠黍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)药蜻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門瓷式,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人语泽,你說我怎么就攤上這事贸典。” “怎么了湿弦?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵瓤漏,是天一觀的道長。 經(jīng)常有香客問我颊埃,道長蔬充,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任班利,我火速辦了婚禮饥漫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘罗标。我一直安慰自己庸队,他們只是感情好积蜻,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著彻消,像睡著了一般竿拆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宾尚,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天丙笋,我揣著相機(jī)與錄音,去河邊找鬼煌贴。 笑死御板,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的牛郑。 我是一名探鬼主播怠肋,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼淹朋!你這毒婦竟也來了笙各?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤础芍,失蹤者是張志新(化名)和其女友劉穎酪惭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體者甲,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年砌创,在試婚紗的時候發(fā)現(xiàn)自己被綠了虏缸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡嫩实,死狀恐怖刽辙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情甲献,我是刑警寧澤宰缤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站晃洒,受9級特大地震影響慨灭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜球及,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一氧骤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吃引,春花似錦筹陵、人聲如沸刽锤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽并思。三九已至,卻和暖如春语稠,著一層夾襖步出監(jiān)牢的瞬間宋彼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工颅筋, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留宙暇,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓议泵,卻偏偏與公主長得像占贫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子先口,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 之前舊項目里的聊天是集成的融云型奥,然而有諸多不方便,很多需求都無法正常且簡單的實現(xiàn)碉京。而且使用聊天的人也并不多厢汹。。谐宙。所...
    Bart_Simpson閱讀 789評論 0 2
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 1,980評論 0 7
  • 以流的方式處理IM通訊問題好處是無需多次建立連接烫葬,另外消息的網(wǎng)絡(luò)開銷少,而xmpp會有很多冗余的信息凡蜻; 使用開源項...
    sea777777閱讀 2,303評論 0 8
  • 在我看來搭综,要把公務(wù)員考試的《申論》搞好,要把握好三件事情即可: 第一件:邏輯 如果邏輯清晰划栓,層次分明兑巾,觀點...
    空谷lmc閱讀 606評論 1 3
  • 2017年4月,面試結(jié)束忠荞,研招辦的短信發(fā)過來蒋歌,我成為一名準(zhǔn)研究生。 回到學(xué)校委煤,大四的尾聲漫長又自由堂油,沒有課程,只有...
    紫凝羽希閱讀 354評論 0 0