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

Useful Information | Learn Pinduoduo’s 5 high-conversion marketing strategies!

Pinduoduo, a new internet celebrity and a three-y...

The top ten "down-to-earth" advertisements of 2019, I am convinced!

I heard that advertisers have received another di...

As application developers, how do we build a performance testing plan?

[51CTO.com Quick Translation] Developing a perfor...

What are the ranking factors for link popularity of a specific page?

The ranking factors for link popularity of a spec...

How can a newbie quickly become a Vlogger? An OPPO Reno2 phone is enough!

From taking photos to recording videos, mobile ph...

How to use SMS to attract and recall lost users?

There are three common methods of user recall or ...

17 Tik Tok tricks to predict how to make a hit

In fact, this article is about creativity. Some o...

Retention or virus? What should a product focus on in its early stages?

Many companies ask the question “How do we acquir...

30 ways to promote your online store

For a novice opening a store, just waiting won’t ...

Form costs reduced by 30%, home decoration advertising case!

With the further deepening of regulation and cont...