需求详解:

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

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

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

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

    脚本开发-参数化之将内容保存为参数.参数数组及参数值获取 by:授客 QQ:1033553122 ----------------接 Part 1--------------- 把内容保存到参数数组 ...

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

    转自:http://blog.sina.com.cn/s/blog_13cc013b50102v49c.html(查看原文) 在VuGen中默认使用{}的字符串称为参数 注意:参数必须在双引号中才能用 ...

  3. IOS开发之功能模块--自定义导航控制器类常用自定义的代码

    前言:本文篇幅不多,但是涉及到的内容却是开发中常用的. 涉及的内容: 1.统一设置导航控制器子控制器的返回按钮. 2.因为修改了系统的返回按钮,所以还需要设置手势事件. 3.隐藏底部的工具条. 这里直 ...

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

    在开发向苹果Apns推送消息服务功能,我们需要根据Apns接受的数据格式进行推送.下面接受我在进行apns推送时候总结的一点apns服务接受的Json数据格式 示例 1: 以下负载包含哦一个简单的 a ...

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

    首先上Boss直聘的功能界面截图,至于交互请读者现在Boss直聘去交互体验:     本人的公司项目要高仿Boss直聘的IM常用语的交互功能,居然花费了我前后17个小时完成,这回自己测试了很多遍,代码 ...

  6. iOS开发之功能模块--根据需求开发横向的子弹盒View

    这个需求是本人工作开发中后期需求要添加的新功能,本人模仿UITableView的代理和数据源方法进行了第一阶段的开发.第二阶段是添加丰富的动画. 这个功能需求描述:能上传添加五个待选头像,五个头像分别 ...

  7. iOS开发之功能模块--推送之坑问题解决

    不管想不想看我后面再开发中总结的经验,但是很值得推荐一位大神写的关于苹果推送,很多内容哦:http://www.cnblogs.com/qiqibo/category/408304.html 苹果开发 ...

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

    前言:好久没写博客,今天来一波.我在实际项目开发中,会遇到这样功能需求:我已经搭好了iOS的UI界面,但是很多界面的子View用了UIView,然后这些UIView中用了UILabel和UIImage ...

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

    创了一个XMPP即时通讯交流群140147825,欢迎大家来交流~我们是一起写代码的弟兄~ 前面几篇,我们讨论了环境的配置,框架的导入和用户登陆,这一篇我们来说说好友模块. 在进入正题之前,我们来说下 ...

随机推荐

  1. JS详细入门教程(上)

    首先,我们看一下DOM级别和兼容性: 之前好像在某本上看到说DOM有0级,实际上,DOM0级标准是不存在的.DOM有1.2.3三个级别.DOM1级由两个模块组成(DOM Core和DOM HTML), ...

  2. 1Z0-053 争议题目解析314

    1Z0-053 争议题目解析314 考试科目:1Z0-053 题库版本:V13.02 题库中原题为: 314.Given the following RMAN commands, choose the ...

  3. Windows Server 2008 下解析二级域名的方法

    昨天去了客户那里部署网站,用的是客户那边的windows server 2008. 本文主要以总结问题点的形式来说. 问题1:本机的数据库是SQL SERVER 2008R2,客户那边的数据库是SQL ...

  4. PHP+MySQL中实现分页

    你只需要在需要添加页的页面加入这几行代码 <?phpinclude 'form.class.php'; $p=new Page(100, 'Demo01.php');//这里需要传递两个参数,参 ...

  5. Mysql并发时经典常见的死锁原因及解决方法

    1.    mysql都有什么锁 MySQL有三种锁的级别:页级.表级.行级. 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最高,并发度最低. 行级锁:开销大,加锁慢:会出现死锁 ...

  6. MVC学习系列13--验证系列之Remote Validation

    大多数的开发者,可能会遇到这样的情况:当我们在创建用户之前,有必要去检查是否数据库中已经存在相同名字的用户.换句话说就是,我们要确保程序中,只有一个唯一的用户名,不能有重复的.相信大多数人都有不同的解 ...

  7. 自己封装的一个JS分享组件

    因为工作的需求之前也封装过一个JS分享插件,集成了我们公司常用的几个分享平台. 但是总感觉之前的结构上很不理想,样式,行为揉成一起,心里想的做的完美,实际上总是很多的偏差,所以这次我对其进行了改版. ...

  8. css3实现光标悬浮滚动菜单

    效果:http://hovertree.com/texiao/css3/21/ 本文所用到的CSS知识请点击效果展示也中第一和第二个链接. 代码: <!DOCTYPE html> < ...

  9. Asp.net 面向接口可扩展框架之使用“类型转化基础服务”测试四种Mapper(AutoMapper、EmitMapper、NLiteMapper及TinyMapper)

    Asp.net 面向接口可扩展框架的“类型转化基础服务”是我认为除了“核心容器”之外最为重要的组成部分 但是前面博文一出,争议很多,为此我再写一篇类型转化基础服务和各种Mapper结合的例子,顺便对各 ...

  10. String和Date、Timestamp之间的转换

    一.String与Date(java.util.Date)互转 1.1 String -> Date String dateStr = "2010/05/04 12:34:23&quo ...