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

WP ≠ Lumia

Since Microsoft officially released WP7, the WP c...

What do WeChat Mini Programs mean to users and businesses?

In the process of establishing a new ecosystem, t...

Difficult to reach users? Try these 3 tips

Operations personnel have their own limitations. ...

Some evil spells in programming languages, never use them

Ever since I watched Gary Bernhardt's highly ...

Traffic thinking is dead, interaction and content marketing are immortal

Recently, I have received messages from some mark...

Guangxi characteristic mineral crystal - pyromorphite

introduction In the international mineral crystal...

How to implement marketing and advertising strategies?

There was once an ultimate question popular in th...

Application and expansion of MVP model in Ctrip Hotels

Preface The hotel business department is one of C...