1.項目使用的第三方開源庫
項目使用了CocoaPods(類似java中的maven)管理常用的第三方庫,一些特殊的單獨引用,下面介紹下比較好用的幾個。
(1)AFNetworking
目前比較推薦的iOS網絡請求組件,默認網絡請求是異步,通過block回調的方式對返回數據進行處理。
需要注意的是AFNetworking對服務器返回的ContentType要求比較嚴格,默認只支持application/json的返回。所以可能需要添加對text/html返回的支持,否則可能無法獲得返回數據。
另外就是文件上傳,這裡推薦使用第二種:
[formData appendPartWithFormData: name:];
[formData appendPartWithFileData: name: fileName: mimeType:];
第一種只需要傳入表單名和文件流,源碼也是根據文件流獲得對應的文件名和文件類型,然後調用第二種方法。但是樓主遇到了使用第一種方法,提交後後台判斷為非文件上傳,無法獲得文件流。還有如果後台是根據文件後綴文件類型,那麼第一種也無法使用。
AFNetworking是異步的,也可以使用同步的網絡請求方法.
(2).FMDB
對sqlite數據庫操作進行了封裝,demo也比較簡單。
(3).MBProgressHUD
也是iOS項目常用的一個組件,用於顯示過渡效果的,比如網絡請求之前顯示loading,網絡結束隱藏loading。建議封裝在BaseViewController中,所有ViewController繼承就能使用。
(4).MJRefresh
這個是傳智播客李明傑老師的作品,自己的oc基礎就是看他的視頻半個周末就基本拿下了。MJRefresh主要用於刷新操作,提供了常用的刷新操作,還有刷新動畫,用著很好用。建議把方法封裝在BaseViewController中,這樣修改刷新操作時,就只需要改動一份。(之前用的舊版MJRefresh,只支持普通的刷新,不支持動畫,後來更新後版本變化比較大,舊的方法已經不推薦使用了,所以還是封裝基類中使用比較好,方便以後修改)
(5).SDWebImage
也是iOS最常用的一個組件,用戶加載網絡圖片,可以緩存到本地。大概原理時,第一次加載後,會根據url加密作為文件名緩存在本地,如果再次加載圖片時,就直接從本地加載。用著也比較簡單。這裡也分享遇到的一個問題,先從網絡加載一張小圖,然後小圖作為占位圖,再從網絡加載一張大圖。
[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
一個TabBar組件,可以方便設置底部菜單的文字圖片,點擊效果,小紅點提示等。
(7).Toast
類似android的toast提示效果,封裝在BaseViewController中,需要的地方進行提示。
(8).XMPPFramework
iOS唯一的xmpp類庫,作者在去年8月份添加了xep-0198協議支持(流管理,用於xmpp斷線重連),但是通過pod進行更新時,無法下載到最新版本,可能0198還沒有完善好,無法作為正式版。
(9).TPKeyboardAvoiding
用戶鍵盤彈出自動計算高度,進行屏幕滾動操作。
(10).AMR
做即時通訊的音頻處理,目前我們的即時通訊使用的錄音文件是m4a,便於web端的音頻播放。
(11).TQRichTextView
用於做富文本視圖控件顯示,用於即時通訊的表情顯示,以及資源評論的富文本顯示。
(12).CSGrowingTextView
用作即時通訊文本框和評論文本框使用,可以顯示多行輸入。
(13).MJExtension
也是李明傑老師的作品,用於json轉model進行使用,有點類似於java中谷歌的Gson。轉換效率據說也很高,使用也比較簡單,只要前後台約定好,json直接就轉成了model。一個工作多年的iOS朋友說,一個項目主要的是對model層的管理,他推薦的是Mantle。不過MJ這個更輕量級點,用著也更加簡單。
3.工具和插件介紹
Xcode
iOS開發的官方工具,也沒別的選擇。有些功能做的確實挺帥的,比如StroyBoard的拖拽事件綁定。不爽的地方就是沒有代碼格式化,另外點擊方法,可能跑到另外一個類中了!!另外左邊的目錄也不會自動發生變化,定位到對應文件,需要command+shift+j
SimPholders2
可以快速找到模擬器對應的沙盒目錄,啟動後右側頂部工具欄有個類似關閉按鍵的按鈕,顯示最近的幾個應用,點擊就進入到了對應的沙盒目錄。
VVDocumenter-Xcode
xcode工具,///生成注解模板,xcode這功能都不給集成,唉。
其他的基本就不用介紹了,有的也不怎麼好用。SVN可以使用Cornerstone,Git可以使用SourceTree,sqlite可以使用SQLite Professional(不過是收費的,免費的只能查看),還可以用火狐浏覽器的sqlite插件。
4.集成友盟
友盟,提供了App和運用的一站式解決方案。公司上個移動項目用到了友盟的推送服務,這個項目中, 還使用了分享,第三方登錄的功能,自己也親自參與到了相關集成。友盟的開發者文檔還算是比較全的,遇到問題可以聯系客服或者到友盟的論壇找解決方案。
(1).關於推送
iOS推送分為本地推送和遠程推送,本地推送是指本地自己彈出信息,另外一個就是遠程推送,當應用未啟動時,也能收到相關推送信息。我們項目沒有使用本地推送,使用的都是友盟的遠程推送。包括消息(聊天)和通知(用戶信息通知)中。用戶在聊天過程中,手機除了發送即時通訊以外,也調用後台接口,發送友盟推送。另外用戶的帖子,評論,關注,點贊等都會由後台調用友盟的推送。
友盟推送(另外一個域名)包括單播,列播,和廣播,其中廣播限定次數每天3次,可以和友盟申請提高次數,其他不限定次數,目前來看單播速度還是挺快的。使用友盟推送,需要在蘋果開發者賬號中,新建兩個推送證書,提交給友盟(友盟有詳細的文檔,可以參考)。可以在友盟後台,把測試設備的deviceToken加到友盟推送的後台,從友盟後台發起推送。(需要64位token,需要通過方法進行計算,直接在xcode或者ituns中拿到token不行)
推送的大概流程就是,手機在第一次啟動app的時候開啟推送服務,手機在啟動app的時候,注冊友盟服務,同時把deviceToken提交到自己的後台,後台可以在需要的時候拿著deviceToken調用友盟的推送接口,友盟再去發起蘋果的推送服務,使對應的設備收到遠程推送信息。
(2).關於第三方登錄和分享
這塊兒都在友盟的社會化分享中,裡面提供了比較全面的文檔。建議第三方分享模塊不用自己特殊設計,可以使用友盟的默認分享模塊(我們項目的分享模塊自己進行了設計,包括了收藏,所以整塊都需要自定義寫UI和寫分享代碼)。關於友盟的第三方登錄和分享需要注意的時,QQ和微信登錄分享,都需要手機上安裝應用,appstore審核會卡這點,所以需要判斷手機是否安裝應用,隱藏沒有安裝應用的圖標,這塊兒友盟的sdk已經有相關的判斷方法(應該是友盟集成了QQ和微信sdk,QQ和微信sdk提供了判斷方法)。
第三方登錄分享需要到相關的平台注冊開發者賬號。微信開發者賬號(注意不是訂閱號)第三方登錄需要交錢才能開通,可以支持微信和朋友圈分享。QQ開發者賬號可以支持QQ和QQ空間分享(QQ微博好像需要微博開發者賬號)。新浪微博需要微博開發者賬號。QQ分享開發階段需要把測試賬號加成開發者賬號的好友才能測試,微博也類似。
第三方登錄自己遇到了QQ提示不是最新版的文本,在友盟論壇中找到了解決方案。
第三方登錄,我們項目集成了QQ,微信,新浪微博登錄。三個平台都能獲得用戶的screen_name(用戶名稱),以及對應的平台唯一的id,其中QQ和微信都是openid,新浪是userid。
第三方分享,文檔提供了分享圖片,視頻,語音。如果是分享url,需要設置對應平台的分享地址,參考解決方案,比如
[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空間,必須指定一張圖片,否則不能分享成功。
第三方分享建議封裝到一個類中,我們項目是幾個詳情頁都有分享,評論,舉報,收藏,點贊等功能。封裝在一個BaseDetailViewController中的,相關頁面繼承,同時傳入對應的資源類型,只用維護一份代碼。
5.即時通訊
即時通訊網上有第三方的解決方案,比如環信,融雲等。我們是自己搭的xmpp服務器,服務器使用的tigase,之前寫過相關的博客,自己去年也做了對應的webim。前段時間看了環信webim的sdk,使用的也是strophe的js類庫,相關實現跟我們的差不多,但是自己搭建xmpp會遇到了不少問題,比如丟消息!所以如果想比較快速的實現im,推薦使用第三方的解決方案。
移動端的丟消息大概是這個樣子。A和B通訊,A發了一條消息給服務器,服務器發給B,但是B網絡不好掉線了,而服務器卻不知道B退出了(B正常退出會給服務器發下線通知),所以消息丟失了。XMPP中有xep-0184協議(消息回執),A給B發消息,消息體中帶一行代碼(要求消息回執),當B收到消息後發送一條回執,證明我收到了。後來XMPP又有了xep-0198協議(流管理),斷線後快速重鏈,同時判斷一定時間收不到消息,就把消息寫離線消息,減少丟消息情況。但是可能網絡情況復雜,加上各種不確定因素,還會出現丟消息的問題。目前比較靠譜的方法就是存所有的聊天記錄,由手機端根據時間點去數據庫拉消息,只要別人發出的消息就不會丟。
這次即時通訊模塊進行了相關改動,也是參考了之前開發人員的一些建議。比如用戶返回home的時候,斷開xmpp連接(iOS進入後台後,只有5秒的處理時間,特殊方法可延長到10分鐘,如果內存不夠,應用隨時就被殺死了)。所以返回home時就斷開,進入應用再連接。同時應用使用狀態下,有心跳檢測,判斷是否保持連接。
考慮到iOS的特殊性,我們采取了xmpp和遠程推送都走的方法,推送的自定義消息體和xmpp消息體一樣,消息的處理方法一樣。用戶聊天發送xmpp消息的同時也調用我們的消息推送接口調用友盟push(push可以設置過期時間,避免特殊情況,推送延時,聊天結束了才收到推送)。一是解決iOS應用未啟動時的推送接收,二是解決xmpp丟消息的問題。
關於推送,AppDelage中有兩個方法,一個是使用中收到推送,不會提示,會直接處理推送信息。另外是程序非使用狀態,收到推送,會進行提示,可以點擊推送消息進入應用,獲取這一條推送消息的推送消息(需要注意,點擊推送啟動應用拿到信息時view還沒有加載,消息不能立刻處理)。
android端因為是真後台,可以後台一直保持運行,無論收到xmpp消息還是友盟推送,都可以自己進行處理,然後自己彈一個本地推送(也有弊端,如果android程序殺死,就無法接受消息和推送)。iOS端因為後台不可控,所以推送使用遠程推送,進入應用連接xmpp再收全部離線消息(不保證友盟推送能否保證及時)。當然大部分都還是正常情況,網絡情況比較好的條件下,就實時收到了xmpp的消息或者遠程推送。我們又不是QQ和微信,只要保證用戶看到的數據能保持一致性就行了(所以QQ和微信就是diao啊)。
根據測試反饋的情況,iOS這個應用的丟消息情況比上個應用有一定改善。具體情況再進一步觀察把。
我們的即時通訊也包括語音和圖片,采用的是http的解決方案(xmpp也支持二進制的傳輸,但是估計沒人那樣用)。具體流程就是先把附件傳到附件服務器拿到附件服務器的地址,再封裝到消息體。接收方收到消息解析的時候,再從附件服務器拿到對應的資源,加載到本地。 同時屏蔽,取消屏蔽等一些實時操作也都會發xmpp,第一時間雙方更新狀態。