Chat module developed in iOS--content preservation logic implementation

Chat module developed in iOS--content preservation logic implementation

Detailed requirements:

In actual development, there may be a need for optimization in the later stage: the chat input box saves the previously entered text to improve the user experience.

In the chat module, the user may enter a number of characters in the input box, but click to exit the chat without clicking Send, or click the user's avatar to confirm the user's information, or, for example, need to send another friend's ID to a friend and have to temporarily exit the current friend chat interface and jump to another interface to find the ID. However, the current chat input box has already entered a number of characters, and the user certainly does not want to delete the previously entered text after exiting. Therefore, it is necessary to temporarily save the string that the user has entered but not sent.

However, it is also necessary to meet the following conditions: 1. To completely kill or exit the application, you need to clear the temporarily saved string; 2. After sending it out, you must delegate the previously temporarily saved string.

start:

At the beginning, I didn't have a good idea about how to implement this part of the logic. I only thought of local serialization, but in fact this is not the best idea, because local serialization is a bit of an overreaction here. In fact, just use the dictionary of global static variables.

As for the specific implementation logic, I also specially read and studied the implementation of the Coding project. After all, this project is a relatively mature project, and the chat module is also very well done. So it is also good to learn from other people's ideas, as the saying goes, standing on the shoulders of giants.

Next, I will directly interpret the logic of saving the content in the chat module in the Coding source code (Learning Coding-iOS Open Source Project Log (I)), instead of talking about the project I developed at work.

1. First, declare global static variables. In Coding, inputStrDict is used to store the string of the input box. I don’t know what inputMediaDict stores for the time being. It should be an element like media:

2. Then encapsulate a lot of logic in this UIMessageInputView class. No methods need to be made public. Just fully utilize the logic of the UIMessageInputView activity cycle.

  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:@ "Reply %@" , _toUser. name ]: @ "Write a comment" ;
  97. } else {
  98. self.placeHolder = @ "Please enter the private message content" ;
  99. }
  100. _inputTextView.selectedRange = NSMakeRange(0, _inputTextView.text.length);
  101. [_inputTextView insertText:inputStr? inputStr: @ "" ];
  102.         
  103. _mediaList = [self inputMedia];
  104. [self mediaListChenged];
  105. }

The above is nothing more than concatenating the name of the chat object into a key value, then storing the string of the current input box into a global static dictionary, and then there are several methods for retrieving and deleting.

3. Let's see where these methods are called:

The save method is placed in the method overridden by the frame, because the input box will switch frames as the keyboard is displayed and hidden. However, the chat module of my company's project was developed by my colleague at the beginning. I found that he used Masonry's layout code to change the position of the input box. Choosing layout constraints means giving up the frame, so where to call the save method should be based on actual needs and actual coding implementation. In addition, when developing this input box at the beginning, you can consider its operation cycle: start editing->editing->end editing. These operation cycles can implement their own methods, just like the life cycle of a controller. In short, there are many ideas, and doing a good job can implement logic that is easy to manage and maintain.

Then find a way to delete it. The method of deletion is to put it at the very beginning of sending the string. Since it has been sent out, the elements stored in the dictionary can be deleted.

In addition, when creating a key, the key string depends on the current chat object, because the content of the current input box must correspond to the current friend object one by one. I cannot save the content of the input box corresponding to the current friend, and then jump to another friend and see the same content. Therefore, the key value needs to be determined based on the string of the current friend, so the set method of the ToUser property is rewritten in the Coding source code:

<<:  A preliminary exploration of the application prospects of VR technology industry: technological innovation defines a wonderful future

>>:  Comparison of the latest shipments of Android and iPhone to see their system market share

Recommend

When Science Meets Doubt: The "Unbreakable Glass" of 1970

Glass is one of the most fascinating materials in...

Source code | Uber's welcome screen

Source code introduction: Uber welcome page. Uber...

The most comprehensive summary of e-commerce operation and marketing terms!

The fastest way to understand an industry is to m...

Your phone battery is not durable again. You ignored these charging details...

Do you sometimes wonder: Why does the battery of ...

Tips for obtaining live streaming traffic, recommended to save!

E-commerce live streaming not only boosted consum...

A clear, complete and reusable solution for recalling lost users

Peter Drucker, the father of modern management, o...

8 hot topics in marketing in 2020!

What I want to share with you today is: In the cu...

Urgent reminder again! Don't take photos of these bugs

During the past May Day holiday The most popular ...

Nowadays, liberal arts students have the final say on the Internet!

Recently, Xiao Nei saw a piece of news that made ...

Unreal Engine UDK official video tutorial

Unreal Engine UDK official video tutorial resourc...