iOS开发之聊天模块--内容保存逻辑实现

需求详解:

  在实际开发中,有可能是在后期优化的时候,会有这么需要优化的需求:聊天输入框保存之前输入的文本,提高用户的良好体验。

   在聊天模块中,用户可能会在输入框输入若干字符,但是没有点击发送就点击退出聊天,或者要点击用户头像确认用户的信息,或者比如需要向好友发送另一个好 友的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

时间: 2024-12-29 17:03:47

iOS开发之聊天模块--内容保存逻辑实现的相关文章

loadrunner 脚本开发-参数化之将内容保存为参数、参数数组及参数值获取

转自:http://blog.sina.com.cn/s/blog_13cc013b50102v49c.html(查看原文) 在VuGen中默认使用{}的字符串称为参数 注意:参数必须在双引号中才能用 将字符串保存为参数 lr_save_string("string you want to save", "arg_name"); 举例:用参数来替换需要打开的url链接 Action2() { lr_save_string("http://172.25.75

0811 iOS开发需要学习哪些内容

1.iOS开发需要学习哪些内容? 2.开发步骤 3.框架 为了方便开发者开发出强大的功能,苹果提供了各种各样的框架 [1]UIKit:创建和管理应用程序的用户界面 [2]QuartzCore:提供动画特效以及通过硬件进行渲染的能力 [3]CoreGraphics:提供2D绘制的基于C的API [4]CoreLocation:使用GPS和WIFI获取位置信息 [5]MapKit:为应用程序提供内嵌地图的接口 [6]AVFoundation:音频.视频处理 [7]--

iOS开发之功能模块--Apns推送中的的json格式介绍

在开发向苹果Apns推送消息服务功能,我们需要根据Apns接受的数据格式进行推送.下面接受我在进行apns推送时候总结的一点apns服务接受的Json数据格式 示例 1: 以下负载包含哦一个简单的 aps 字典.它使用字符串而不是字典作为 alert 的值,该负载同样包含了一个自定义的属性数组. { "aps" : { "alert" : "message" },//alert表示推送的消息文本 "parm" : [ &quo

iOS开发——使用技术OC篇&保存(获取)图片到(自定义)相册

保存(获取)图片到(自定义)相册 最近在学 iOS相关技术(绘图篇实现画板功能)的时候设计到了两个常用的知识点,那就是保存图片到相册和葱相册中获取图片. 只是个人比较好奇拓展一些技术,说的难听点叫做装牛角尖,好听点就是为了装逼而已,所以在保存相册的时候使用真及测试发现不能保存到我iPhone里 main的自定义相册里面,就查看文档和资料,也借鉴别人的分享实现了想要的功能,就把他给记录下来,这个虽然没有直接保存和获取常用但是也是一项很好的实用技术. 一:首先来看看怎么获取相册的图片: 1 // 弹

iOS开发--XMPPFramework--好友模块(四)

前面几篇,我们讨论了环境的配置,框架的导入和用户登陆,这一篇我们来说说好友模块. 在进入正题之前,我们来说下调试. 首先,打开偏好设置,看一下Openfire服务器和MySQL是否打开,记得先打开MySQL,再打开Openfire,随后,点击Open Admin ConConsole, 出现下面的页面,就成功了. 输入用户名和密码,登录,出现这个界面: 随后,点击导航栏上的“用户/组”,出现了用户和聊天组的管理 我们可以看到,用户中有两个,一个是管理员,一个是普通用户zhangsan,我们点击左

IOS开发之功能模块--给任意的UIView添加点击事件

前言:好久没写博客,今天来一波.我在实际项目开发中,会遇到这样功能需求:我已经搭好了iOS的UI界面,但是很多界面的子View用了UIView,然后这些UIView中用了UILabel和UIImageView,然后接着需求要这些View能够有点击事件,比如一点击就跳转到某个控制器.一开始懵逼了,难道我还要把他们全部改成UIButton,但是UIButton不好添加子View,难道我还要全部自定义一下UIButton,就算自定义好了,在项目已经打好的界面还是要一个个替换,多麻烦.所以就想到通过UI

iOS开发之功能模块--高仿Boss直聘的常用语的开发

首先上Boss直聘的功能界面截图,至于交互请读者现在Boss直聘去交互体验:     项目要高仿Boss直聘的IM常用语的交互功能,居然花费了我前后17个小时完成,这回自己测试了很多遍,代码质量很高,交互很流畅,仿真度也很高,重点综合性的用到了很多东西:runtime.代理传值.block传值.textView的系统通知监听.富文本.自定义封装.本地化增删改等等.其实这些都是基础,重点是功能的交互逻辑或者是业务逻辑的分析,然后正确实现,并经过尽可能多情况的自我测试通过,没有基础Bug,也没有任何

iOS开发之功能模块--用runtime给UIView类别拓展PressMenu工具

这是个很有用的列别工具类,在聊天对话框添加和QQ一样的"复制.粘贴.取消"等选项,而且使用起来很方便,只要找到聊天泡泡内部的某个View,比如Label或者背景冒泡的UIImageView,直接add...即可实现下面的效果: 直接上源码: UIView+PressMenu.h 1 #import <UIKit/UIKit.h> 2 3 @interface UIView (PressMenu) 4 @property (strong, nonatomic) NSArray

iOS开发之功能模块--高仿Boss直聘的IM界面交互功能

本人公司项目属于社交类,高仿Boss直聘早期的版本,现在Boss直聘界面风格,交互风格都不如Boss直聘以前版本的好看. 本人通过iPhone模拟器和本人真机对聊,将完成的交互功能通过Mac截屏模拟器来录制基本的交互功能. 界面因为动态截图工具本身不完美,截屏失真,所以存在有的部分UI颜色稍微变化了,比如白色稍微变灰暗色,不是项目本身的问题. 因为是本公司项目,不提供源码,只提供交互动态图仅供观赏??. (备注:Boss直聘分为个人端和企业端) 1.基本功能描述: 在个人端,一开始会话列表没有任