iOS開發之聊天模塊--內容保存邏輯實現

来源:http://www.cnblogs.com/goodboy-heyang/archive/2016/08/17/5782201.html
-Advertisement-
Play Games

需求詳解: 在實際開發中,有可能是在後期優化的時候,會有這麼需要優化的需求:聊天輸入框保存之前輸入的文本,提高用戶的良好體驗。 在聊天模塊中,用戶可能會在輸入框輸入若幹字元,但是沒有點擊發送就點擊退出聊天,或者要點擊用戶頭像確認用戶的信息,或者比如需要向好友發送另一個好 友的ID不得不暫時退出當前好 ...


需求詳解:

  在實際開發中,有可能是在後期優化的時候,會有這麼需要優化的需求:聊天輸入框保存之前輸入的文本,提高用戶的良好體驗。

   在聊天模塊中,用戶可能會在輸入框輸入若幹字元,但是沒有點擊發送就點擊退出聊天,或者要點擊用戶頭像確認用戶的信息,或者比如需要向好友發送另一個好 友的ID不得不暫時退出當前好友聊天界面跳轉找到別的界面找ID,然而當前聊天輸入框也已經輸入好了若幹字元,用戶當然不希望退出之後就刪除之前輸入好的 文字。所以這裡就需要暫時保存用戶輸入好的但是沒有發送出去的字元串。

  但是,還需要滿足1、完全殺掉或者完全退出應用就需要清楚這個暫時保存的字元串,2、發送出去之後,肯定就要delegate之前暫時保存的字元串嘍。

 

開始:

這部分邏輯的實現一開始我沒怎麼比較好的頭緒,只想到本地序列化,但實際上這個還不算是最好的思路,因為本地序列化用到這裡有點小題大做了,其實只要用全局靜態變數的字典就可以了。

具體實現的邏輯,我也特意閱讀研究了Coding項目的實現,畢竟這個項目是比較成熟的項目,聊天模塊也做的很不錯,所以學學別人的思想,正所謂站在巨人的肩膀上,也是很好的哦。

 那麼下麵,我就直接解讀Coding源碼(學習Coding-iOS開源項目日誌(一))在這個聊天模塊內容保存的邏輯吧,就不拿自己工作開發的項目來講了。

1、首先聲明全局static的變數,Coding中用inputStrDict存儲輸入框的字元串,而inputMediaDict我暫時不知道它具體存什麼的,應該是media之類的元素:

 

2、然後將很多邏輯封裝在這個UIMessageInputView類中,方法都不用公開,完全利用UIMessageInputView活動周期的邏輯就可以了。

 

  1 #pragma mark remember input
  2 
  3 - (NSMutableDictionary *)shareInputStrDict{
  4     if (!_inputStrDict) {
  5         _inputStrDict = [[NSMutableDictionary alloc] init];
  6     }
  7     return _inputStrDict;
  8 }
  9 
 10 - (NSMutableDictionary *)shareInputMediaDict{
 11     if (!_inputMediaDict) {
 12         _inputMediaDict = [[NSMutableDictionary alloc] init];
 13     }
 14     return _inputMediaDict;
 15 }
 16 
 17 - (NSString *)inputKey{
 18     NSString *inputKey = nil;
 19     if (_contentType == UIMessageInputViewContentTypePriMsg) {
 20         inputKey = [NSString stringWithFormat:@"privateMessage_%@", self.toUser.global_key];
 21     }else{
 22         if (_commentOfId) {
 23             switch (_contentType) {
 24                 case UIMessageInputViewContentTypeTweet:
 25                     inputKey = [NSString stringWithFormat:@"tweet_%@_%@", _commentOfId.stringValue, _toUser.global_key.length > 0? _toUser.global_key:@""];
 26                     break;
 27                 case UIMessageInputViewContentTypeTopic:
 28                     inputKey = [NSString stringWithFormat:@"topic_%@_%@", _commentOfId.stringValue, _toUser.global_key.length > 0? _toUser.global_key:@""];
 29                     break;
 30                 case UIMessageInputViewContentTypeTask:
 31                     inputKey = [NSString stringWithFormat:@"task_%@_%@", _commentOfId.stringValue, _toUser.global_key.length > 0? _toUser.global_key:@""];
 32                     break;
 33                 default:
 34                     break;
 35             }
 36         }
 37     }
 38     return inputKey;
 39 }
 40 
 41 - (NSString *)inputStr{
 42     NSString *inputKey = [self inputKey];
 43     if (inputKey) {
 44         DebugLog(@"inputStr_get:%@",[[self shareInputStrDict] objectForKey:inputKey]);
 45         return [[self shareInputStrDict] objectForKey:inputKey];
 46     }
 47     return nil;
 48 }
 49 
 50 - (void)deleteInputData{
 51     NSString *inputKey = [self inputKey];
 52     DebugLog(@"inputKey_delegate:%@",inputKey);
 53     if (inputKey) {
 54         [[self shareInputStrDict] removeObjectForKey:inputKey];
 55         [[self shareInputMediaDict] removeObjectForKey:inputKey];
 56     }
 57 }
 58 
 59 - (void)saveInputStr{
 60     NSString *inputStr = _inputTextView.text;
 61     NSString *inputKey = [self inputKey];
 62     DebugLog(@"inputKey_save:%@",inputKey);
 63     if (inputKey && inputKey.length > 0) {
 64         if (inputStr && inputStr.length > 0) {
 65             [[self shareInputStrDict] setObject:inputStr forKey:inputKey];
 66         }else{
 67             [[self shareInputStrDict] removeObjectForKey:inputKey];
 68         }
 69     }
 70 }
 71 
 72 - (void)saveInputMedia{
 73     NSString *inputKey = [self inputKey];
 74     if (inputKey && inputKey.length > 0) {
 75         if (_mediaList.count > 0) {
 76             [[self shareInputMediaDict] setObject:_mediaList forKey:inputKey];
 77         }else{
 78             [[self shareInputMediaDict] removeObjectForKey:inputKey];
 79         }
 80     }
 81 }
 82 
 83 - (NSMutableArray *)inputMedia{
 84     NSString *inputKey = [self inputKey];
 85     if (inputKey) {
 86         return [[self shareInputMediaDict] objectForKey:inputKey];
 87     }
 88     return nil;
 89 }
 90 
 91 - (void)setToUser:(User *)toUser{
 92     _toUser = toUser;
 93     NSString *inputStr = [self inputStr];
 94     if (_inputTextView) {
 95         if (_contentType != UIMessageInputViewContentTypePriMsg) {
 96             self.placeHolder = _toUser? [NSString stringWithFormat:@"回覆 %@", _toUser.name]: @"撰寫評論";
 97         }else{
 98             self.placeHolder = @"請輸入私信內容";
 99         }
100         _inputTextView.selectedRange = NSMakeRange(0, _inputTextView.text.length);
101         [_inputTextView insertText:inputStr? inputStr: @""];
102         
103         _mediaList = [self inputMedia];
104         [self mediaListChenged];
105     }
106 }

上面無非就是通過聊天對象的名字拼接成key值,然後對應存儲當前輸入框的字元串到全局static的字典中,然後是取出、刪除的幾個方法。

3、再看看那哪些地方調用了這些方法:

保 存的方法,放在frame重寫的方法里,因為輸入框會隨著鍵盤的現實和隱藏而切換frame,不過我公司的項目一開始聊天模塊是我同事開發的,我發現他用 Masonry的佈局代碼去變換輸入框的位置,選擇了佈局約束也就意味著放棄了frame,所以何處調用save方法還是要根據實際需求和實際的編碼實 現。另外,其實在最開始開發這個輸入框的時候,可以考慮其運作的周期:開始編輯->正在編輯->結束編輯,這些運作周期是可以實現出各自的方 法,就和一個控制器的生命周期一樣。總之思路很多,做好是能實現出好管理好維護的邏輯。

 然後找找刪除的方法,刪除的方法是放在將字元串發出去的最前面,因為已經發送出去了,是可以將字典中存儲的元素刪除了去。

另外,在創建key的時候,這個key字元串是依賴當前聊天對象的,因為當前輸入框的內容要和當前好友對象一一對應,不能我保存了當前好友對應的輸入框內容,跳到別的好友卻又出現了一樣的內容。所以key值需要依據當前好友的字元串來決定,所以Coding源碼中重寫了ToUser屬性的set方法:

 

尊重勞動成果:http://www.cnblogs.com/goodboy-heyang/p/5782201.html

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • localStorage html5標準 Web 存儲現在的主流瀏覽器,包括IE 8+、Chrome 4+、Firefox 3.5+、Opera 10.5+、Safari 4+、iPhone 2+、Android 2+等,都支持localStorage本地存儲功能。 localStorage沒有時間 ...
  • 1.概述 在項目中經常遇到列表中對覆選框進行勾選操作,全選。。。反選。。 2. example ...
  • 第一: webpack只是構建 webpack-dev-server除了構建,還提供web服務 第二:webpack.config.json的路徑參數 顯然,entry都一樣,因為都要知道需要構建的文件在哪裡 那麼區別就在於 output了 path和webpack一起,指明構建 之後 輸出文件的位 ...
  • Express是基於Node.js平臺開發的Web應用開發框架,下麵我們入手學習。 官網 : http://www.expressjs.com.cn/ github:https://github.com/expressjs/express Express生成器 1、生成express全局指令npm ...
  • [1]視窗位置 [2]視窗大小 [3]打開視窗 [4]關閉視窗 ...
  • 在上面兩篇分別說明瞭設計中較為簡單也是很關鍵的實踐點。 第一模塊劃分,它是根據每個模塊所承載的業務,進行劃分,是應用程式一個靜態的描述。 第二合理組合,它是是將每個模塊調動起來,共同實現業務,是一個準動態的說明。 今天主要說明真個應用程式中消息和數據,以及如何迴圈,是完全動態的。同時也簡單的提到各種 ...
  • 1、界面上一個輸入框,一個按鈕,一個webview 。點按鈕,webview顯示輸入框中輸入的url的頁面。 @IBOutlet var wv:UIWebView = nil //定義一個UIWebView @IBOutlet var btnGo: UIView = nil //定義一個按鈕 @IB ...
  • AFNetworking的封裝 特點 1.將AFNetworking 3.0封裝.能夠很好享受蘋果開發中的面向對象開發思想 . 2.其中也提供幾種方法,來請求數據.包括:GET請求/POST請求/Upload請求. 3.調用的方法,在下麵詳細說明 使用方法 1.導入AFNetworking 文件夾 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...