1.項(xiàng)目使用的第三方開(kāi)源庫(kù)
項(xiàng)目使用了CocoaPods(類似java中的maven)管理常用的第三方庫(kù),一些特殊的單獨(dú)引用,下面介紹下比較好用的幾個(gè)。
(1)AFNetworking
目前比較推薦的iOS網(wǎng)絡(luò)請(qǐng)求組件胧华,默認(rèn)網(wǎng)絡(luò)請(qǐng)求是異步慌随,通過(guò)block回調(diào)的方式對(duì)返回?cái)?shù)據(jù)進(jìn)行處理拜秧。
需要注意的是AFNetworking對(duì)服務(wù)器返回的ContentType要求比較嚴(yán)格屹耐,默認(rèn)只支持application/json的返回期奔。所以可能需要添加對(duì)text/html返回的支持厅须,否則可能無(wú)法獲得返回?cái)?shù)據(jù)仿畸。
另外就是文件上傳,這里推薦使用第二種:
[formData appendPartWithFormData: name:];
[formData appendPartWithFileData: name: fileName: mimeType:];
第一種只需要傳入表單名和文件流九杂,源碼也是根據(jù)文件流獲得對(duì)應(yīng)的文件名和文件類型颁湖,然后調(diào)用第二種方法。但是樓主遇到了使用第一種方法例隆,提交后后臺(tái)判斷為非文件上傳甥捺,無(wú)法獲得文件流。還有如果后臺(tái)是根據(jù)文件后綴文件類型镀层,那么第一種也無(wú)法使用镰禾。
AFNetworking是異步的,也可以使用同步的網(wǎng)絡(luò)請(qǐng)求方法.
(2).FMDB
對(duì)sqlite數(shù)據(jù)庫(kù)操作進(jìn)行了封裝唱逢,demo也比較簡(jiǎn)單吴侦。
(3).MBProgressHUD
也是iOS項(xiàng)目常用的一個(gè)組件,用于顯示過(guò)渡效果的坞古,比如網(wǎng)絡(luò)請(qǐng)求之前顯示loading备韧,網(wǎng)絡(luò)結(jié)束隱藏loading。建議封裝在BaseViewController中痪枫,所有ViewController繼承就能使用织堂。
(4).MJRefresh
這個(gè)是傳智播客李明杰老師的作品,自己的oc基礎(chǔ)就是看他的視頻半個(gè)周末就基本拿下了奶陈。MJRefresh主要用于刷新操作易阳,提供了常用的刷新操作,還有刷新動(dòng)畫(huà)吃粒,用著很好用潦俺。建議把方法封裝在BaseViewController中,這樣修改刷新操作時(shí),就只需要改動(dòng)一份事示。(之前用的舊版MJRefresh早像,只支持普通的刷新,不支持動(dòng)畫(huà)很魂,后來(lái)更新后版本變化比較大扎酷,舊的方法已經(jīng)不推薦使用了,所以還是封裝基類中使用比較好遏匆,方便以后修改)
(5).SDWebImage
也是iOS最常用的一個(gè)組件法挨,用戶加載網(wǎng)絡(luò)圖片,可以緩存到本地幅聘。大概原理時(shí)凡纳,第一次加載后,會(huì)根據(jù)url加密作為文件名緩存在本地帝蒿,如果再次加載圖片時(shí)荐糜,就直接從本地加載。用著也比較簡(jiǎn)單葛超。這里也分享遇到的一個(gè)問(wèn)題暴氏,先從網(wǎng)絡(luò)加載一張小圖,然后小圖作為占位圖绣张,再?gòu)木W(wǎng)絡(luò)加載一張大圖答渔。
[imageView sd_setImageWithURL:[NSURL URLWithString:imageURLString] placeholderImage:DefaultPostPic];
[imageView sd_setImageWithURL:[NSURL URLWithString:_bigImageURLStringArray[i]] placeholderImage:imageView.image options:SDWebImageDelayPlaceholder completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
}];
(6).RDVTabBarController
一個(gè)TabBar組件,可以方便設(shè)置底部菜單的文字圖片侥涵,點(diǎn)擊效果沼撕,小紅點(diǎn)提示等。
(7).Toast
類似android的toast提示效果芜飘,封裝在BaseViewController中务豺,需要的地方進(jìn)行提示。
(8).XMPPFramework
iOS唯一的xmpp類庫(kù)嗦明,作者在去年8月份添加了xep-0198協(xié)議支持(流管理笼沥,用于xmpp斷線重連),但是通過(guò)pod進(jìn)行更新時(shí)娶牌,無(wú)法下載到最新版本奔浅,可能0198還沒(méi)有完善好,無(wú)法作為正式版裙戏。
(9).TPKeyboardAvoiding
用戶鍵盤彈出自動(dòng)計(jì)算高度乘凸,進(jìn)行屏幕滾動(dòng)操作厕诡。
(10).AMR
做即時(shí)通訊的音頻處理累榜,目前我們的即時(shí)通訊使用的錄音文件是m4a,便于web端的音頻播放。
(11).TQRichTextView
用于做富文本視圖控件顯示壹罚,用于即時(shí)通訊的表情顯示葛作,以及資源評(píng)論的富文本顯示。
(12).CSGrowingTextView
用作即時(shí)通訊文本框和評(píng)論文本框使用猖凛,可以顯示多行輸入赂蠢。
(13).MJExtension
也是李明杰老師的作品,用于json轉(zhuǎn)model進(jìn)行使用辨泳,有點(diǎn)類似于java中谷歌的Gson虱岂。轉(zhuǎn)換效率據(jù)說(shuō)也很高,使用也比較簡(jiǎn)單菠红,只要前后臺(tái)約定好第岖,json直接就轉(zhuǎn)成了model。一個(gè)工作多年的iOS朋友說(shuō)试溯,一個(gè)項(xiàng)目主要的是對(duì)model層的管理蔑滓,他推薦的是Mantle。不過(guò)MJ這個(gè)更輕量級(jí)點(diǎn),用著也更加簡(jiǎn)單遇绞。
3.工具和插件介紹
Xcode
iOS開(kāi)發(fā)的官方工具键袱,也沒(méi)別的選擇。有些功能做的確實(shí)挺帥的摹闽,比如StroyBoard的拖拽事件綁定蹄咖。不爽的地方就是沒(méi)有代碼格式化,另外點(diǎn)擊方法钩骇,可能跑到另外一個(gè)類中了1仍濉!另外左邊的目錄也不會(huì)自動(dòng)發(fā)生變化倘屹,定位到對(duì)應(yīng)文件银亲,需要command+shift+j
SimPholders2
可以快速找到模擬器對(duì)應(yīng)的沙盒目錄,啟動(dòng)后右側(cè)頂部工具欄有個(gè)類似關(guān)閉按鍵的按鈕纽匙,顯示最近的幾個(gè)應(yīng)用务蝠,點(diǎn)擊就進(jìn)入到了對(duì)應(yīng)的沙盒目錄。
VVDocumenter-Xcode
xcode工具烛缔,///生成注解模板馏段,xcode這功能都不給集成,唉践瓷。
其他的基本就不用介紹了院喜,有的也不怎么好用。SVN可以使用Cornerstone晕翠,Git可以使用SourceTree喷舀,sqlite可以使用SQLite Professional(不過(guò)是收費(fèi)的砍濒,免費(fèi)的只能查看),還可以用火狐瀏覽器的sqlite插件硫麻。
4.集成友盟
友盟爸邢,提供了App和運(yùn)用的一站式解決方案。公司上個(gè)移動(dòng)項(xiàng)目用到了友盟的推送服務(wù)拿愧,這個(gè)項(xiàng)目中, 還使用了分享杠河,第三方登錄的功能,自己也親自參與到了相關(guān)集成浇辜。友盟的開(kāi)發(fā)者文檔還算是比較全的券敌,遇到問(wèn)題可以聯(lián)系客服或者到友盟的論壇找解決方案。
(1).關(guān)于推送
iOS推送分為本地推送和遠(yuǎn)程推送柳洋,本地推送是指本地自己彈出信息陪白,另外一個(gè)就是遠(yuǎn)程推送,當(dāng)應(yīng)用未啟動(dòng)時(shí)膳灶,也能收到相關(guān)推送信息咱士。我們項(xiàng)目沒(méi)有使用本地推送,使用的都是友盟的遠(yuǎn)程推送轧钓。包括消息(聊天)和通知(用戶信息通知)中序厉。用戶在聊天過(guò)程中,手機(jī)除了發(fā)送即時(shí)通訊以外毕箍,也調(diào)用后臺(tái)接口弛房,發(fā)送友盟推送。另外用戶的帖子而柑,評(píng)論文捶,關(guān)注,點(diǎn)贊等都會(huì)由后臺(tái)調(diào)用友盟的推送媒咳。
友盟推送(另外一個(gè)域名)包括單播粹排,列播,和廣播涩澡,其中廣播限定次數(shù)每天3次顽耳,可以和友盟申請(qǐng)?zhí)岣叽螖?shù),其他不限定次數(shù)妙同,目前來(lái)看單播速度還是挺快的射富。使用友盟推送,需要在蘋(píng)果開(kāi)發(fā)者賬號(hào)中粥帚,新建兩個(gè)推送證書(shū)胰耗,提交給友盟(友盟有詳細(xì)的文檔,可以參考)芒涡〔竦疲可以在友盟后臺(tái)掂恕,把測(cè)試設(shè)備的deviceToken加到友盟推送的后臺(tái),從友盟后臺(tái)發(fā)起推送弛槐。(需要64位token,需要通過(guò)方法進(jìn)行計(jì)算依啰,直接在xcode或者ituns中拿到token不行)
推送的大概流程就是乎串,手機(jī)在第一次啟動(dòng)app的時(shí)候開(kāi)啟推送服務(wù),手機(jī)在啟動(dòng)app的時(shí)候速警,注冊(cè)友盟服務(wù)叹誉,同時(shí)把deviceToken提交到自己的后臺(tái),后臺(tái)可以在需要的時(shí)候拿著deviceToken調(diào)用友盟的推送接口闷旧,友盟再去發(fā)起蘋(píng)果的推送服務(wù)长豁,使對(duì)應(yīng)的設(shè)備收到遠(yuǎn)程推送信息。
(2).關(guān)于第三方登錄和分享
這塊兒都在友盟的社會(huì)化分享中忙灼,里面提供了比較全面的文檔匠襟。建議第三方分享模塊不用自己特殊設(shè)計(jì),可以使用友盟的默認(rèn)分享模塊(我們項(xiàng)目的分享模塊自己進(jìn)行了設(shè)計(jì)该园,包括了收藏酸舍,所以整塊都需要自定義寫(xiě)UI和寫(xiě)分享代碼)。關(guān)于友盟的第三方登錄和分享需要注意的時(shí)里初,QQ和微信登錄分享啃勉,都需要手機(jī)上安裝應(yīng)用,appstore審核會(huì)卡這點(diǎn)双妨,所以需要判斷手機(jī)是否安裝應(yīng)用淮阐,隱藏沒(méi)有安裝應(yīng)用的圖標(biāo),這塊兒友盟的sdk已經(jīng)有相關(guān)的判斷方法(應(yīng)該是友盟集成了QQ和微信sdk刁品,QQ和微信sdk提供了判斷方法)泣特。
第三方登錄分享需要到相關(guān)的平臺(tái)注冊(cè)開(kāi)發(fā)者賬號(hào)。微信開(kāi)發(fā)者賬號(hào)(注意不是訂閱號(hào))第三方登錄需要交錢才能開(kāi)通挑随,可以支持微信和朋友圈分享群扶。QQ開(kāi)發(fā)者賬號(hào)可以支持QQ和QQ空間分享(QQ微博好像需要微博開(kāi)發(fā)者賬號(hào))。新浪微博需要微博開(kāi)發(fā)者賬號(hào)镀裤。QQ分享開(kāi)發(fā)階段需要把測(cè)試賬號(hào)加成開(kāi)發(fā)者賬號(hào)的好友才能測(cè)試竞阐,微博也類似。
第三方登錄自己遇到了QQ提示不是最新版的文本暑劝,在友盟論壇中找到了解決方案骆莹。
第三方登錄,我們項(xiàng)目集成了QQ担猛,微信幕垦,新浪微博登錄丢氢。三個(gè)平臺(tái)都能獲得用戶的screen_name(用戶名稱),以及對(duì)應(yīng)的平臺(tái)唯一的id先改,其中QQ和微信都是openid疚察,新浪是userid。
第三方分享仇奶,文檔提供了分享圖片貌嫡,視頻,語(yǔ)音该溯。如果是分享url岛抄,需要設(shè)置對(duì)應(yīng)平臺(tái)的分享地址,參考解決方案狈茉,比如
[UMSocialData defaultData].extConfig.qqData.url = shareUrl;
[UMSocialData defaultData].extConfig.qzoneData.url = shareUrl;
[UMSocialData defaultData].extConfig.wechatSessionData.url = shareUrl;
[UMSocialData defaultData].extConfig.wechatTimelineData.url = shareUrl;
另外分享到QQ空間夫椭,必須指定一張圖片,否則不能分享成功氯庆。
第三方分享建議封裝到一個(gè)類中蹭秋,我們項(xiàng)目是幾個(gè)詳情頁(yè)都有分享,評(píng)論堤撵,舉報(bào)感凤,收藏,點(diǎn)贊等功能粒督。封裝在一個(gè)BaseDetailViewController中的陪竿,相關(guān)頁(yè)面繼承,同時(shí)傳入對(duì)應(yīng)的資源類型屠橄,只用維護(hù)一份代碼族跛。
5.即時(shí)通訊
即時(shí)通訊網(wǎng)上有第三方的解決方案,比如環(huán)信锐墙,融云等礁哄。我們是自己搭的xmpp服務(wù)器,服務(wù)器使用的tigase溪北,之前寫(xiě)過(guò)相關(guān)的博客桐绒,自己去年也做了對(duì)應(yīng)的webim。前段時(shí)間看了環(huán)信webim的sdk之拨,使用的也是strophe的js類庫(kù)茉继,相關(guān)實(shí)現(xiàn)跟我們的差不多,但是自己搭建xmpp會(huì)遇到了不少問(wèn)題蚀乔,比如丟消息烁竭!所以如果想比較快速的實(shí)現(xiàn)im,推薦使用第三方的解決方案吉挣。
移動(dòng)端的丟消息大概是這個(gè)樣子派撕。A和B通訊婉弹,A發(fā)了一條消息給服務(wù)器,服務(wù)器發(fā)給B终吼,但是B網(wǎng)絡(luò)不好掉線了镀赌,而服務(wù)器卻不知道B退出了(B正常退出會(huì)給服務(wù)器發(fā)下線通知),所以消息丟失了际跪。XMPP中有xep-0184協(xié)議(消息回執(zhí))商佛,A給B發(fā)消息,消息體中帶一行代碼(要求消息回執(zhí))垫卤,當(dāng)B收到消息后發(fā)送一條回執(zhí),證明我收到了出牧。后來(lái)XMPP又有了xep-0198協(xié)議(流管理)穴肘,斷線后快速重鏈,同時(shí)判斷一定時(shí)間收不到消息舔痕,就把消息寫(xiě)離線消息评抚,減少丟消息情況。但是可能網(wǎng)絡(luò)情況復(fù)雜伯复,加上各種不確定因素慨代,還會(huì)出現(xiàn)丟消息的問(wèn)題。目前比較靠譜的方法就是存所有的聊天記錄啸如,由手機(jī)端根據(jù)時(shí)間點(diǎn)去數(shù)據(jù)庫(kù)拉消息侍匙,只要?jiǎng)e人發(fā)出的消息就不會(huì)丟。
這次即時(shí)通訊模塊進(jìn)行了相關(guān)改動(dòng)叮雳,也是參考了之前開(kāi)發(fā)人員的一些建議想暗。比如用戶返回home的時(shí)候,斷開(kāi)xmpp連接(iOS進(jìn)入后臺(tái)后帘不,只有5秒的處理時(shí)間说莫,特殊方法可延長(zhǎng)到10分鐘,如果內(nèi)存不夠寞焙,應(yīng)用隨時(shí)就被殺死了)储狭。所以返回home時(shí)就斷開(kāi),進(jìn)入應(yīng)用再連接捣郊。同時(shí)應(yīng)用使用狀態(tài)下辽狈,有心跳檢測(cè),判斷是否保持連接呛牲。
考慮到iOS的特殊性稻艰,我們采取了xmpp和遠(yuǎn)程推送都走的方法,推送的自定義消息體和xmpp消息體一樣侈净,消息的處理方法一樣尊勿。用戶聊天發(fā)送xmpp消息的同時(shí)也調(diào)用我們的消息推送接口調(diào)用友盟push(push可以設(shè)置過(guò)期時(shí)間僧凤,避免特殊情況,推送延時(shí)元扔,聊天結(jié)束了才收到推送)躯保。一是解決iOS應(yīng)用未啟動(dòng)時(shí)的推送接收,二是解決xmpp丟消息的問(wèn)題澎语。
關(guān)于推送途事,AppDelage中有兩個(gè)方法,一個(gè)是使用中收到推送擅羞,不會(huì)提示尸变,會(huì)直接處理推送信息。另外是程序非使用狀態(tài)减俏,收到推送召烂,會(huì)進(jìn)行提示,可以點(diǎn)擊推送消息進(jìn)入應(yīng)用娃承,獲取這一條推送消息的推送消息(需要注意奏夫,點(diǎn)擊推送啟動(dòng)應(yīng)用拿到信息時(shí)view還沒(méi)有加載,消息不能立刻處理)历筝。
android端因?yàn)槭钦婧笈_(tái)酗昼,可以后臺(tái)一直保持運(yùn)行,無(wú)論收到xmpp消息還是友盟推送梳猪,都可以自己進(jìn)行處理麻削,然后自己彈一個(gè)本地推送(也有弊端,如果android程序殺死春弥,就無(wú)法接受消息和推送)碟婆。iOS端因?yàn)楹笈_(tái)不可控,所以推送使用遠(yuǎn)程推送惕稻,進(jìn)入應(yīng)用連接xmpp再收全部離線消息(不保證友盟推送能否保證及時(shí))竖共。當(dāng)然大部分都還是正常情況,網(wǎng)絡(luò)情況比較好的條件下俺祠,就實(shí)時(shí)收到了xmpp的消息或者遠(yuǎn)程推送公给。我們又不是QQ和微信,只要保證用戶看到的數(shù)據(jù)能保持一致性就行了(所以QQ和微信就是diao爸┰)淌铐。
根據(jù)測(cè)試反饋的情況,iOS這個(gè)應(yīng)用的丟消息情況比上個(gè)應(yīng)用有一定改善蔫缸。具體情況再進(jìn)一步觀察把腿准。
我們的即時(shí)通訊也包括語(yǔ)音和圖片,采用的是http的解決方案(xmpp也支持二進(jìn)制的傳輸,但是估計(jì)沒(méi)人那樣用)吐葱。具體流程就是先把附件傳到附件服務(wù)器拿到附件服務(wù)器的地址街望,再封裝到消息體。接收方收到消息解析的時(shí)候弟跑,再?gòu)母郊?wù)器拿到對(duì)應(yīng)的資源灾前,加載到本地。 同時(shí)屏蔽孟辑,取消屏蔽等一些實(shí)時(shí)操作也都會(huì)發(fā)xmpp哎甲,第一時(shí)間雙方更新?tīng)顟B(tài)。