IOS developers use the system to push Notifaction and polling to implement a Simple Chat System

Source: Internet
Author: User

IOS developers use the system to push Notifaction and polling to implement a Simple Chat System

Let's not talk about it. Let's take a look at the chat software interface:




First, a UItableView and a view are dragged on the StoryBoard to input text or speech. The button on the right is used to switch between text and speech:


There are three types of IDs in the chat: orderID: chat idmessageID: IDsessionID of each message: the session id of each order. If it is empty, request by orderID.

Then, perform some interface operations and initialization operations in viewDidLoad:
1. Set the headView of tableview.


2. initialize recordings, user portraits, and obtain order details
   // Change the recording [self initRecord]; // obtain the user avatar [self getHeadImg]; // obtain the Order details [self getOrderDetailInfo];
3. In viewWillAppear: a. registers some keyboard and chat notifications. B. Starts a 20-second NSTimer Round Robin to get chat messages.
C. self. chatArray reads the chat message of the database. If the array is empty, tableviewd is refreshed if it is not empty. If it is from the rating page, the order status is refreshed.
4. Check the code of the polling message:
# Pragma mark-polling message-(void) runLoopMessage {SpeakType speaker = [YCChatInfo getSpeakerPassengerBy: self. orderInfo. bigType]; [[YCReceiveMessageCenter defaultMessageCenter] getMessageListBySpeaker: speaker isRemote: NO andPushId: nil];}
The first code is to get the session type. An enumeration value is defined here, which mainly includes the following roles:
// Session type enum SpeakType {// Business YCDriverType = 11, ycpasloud = 12, YCSystem = 13, // v5.2.2 Add the system role YCLoctionAutoReply = 14, // v5.2.2 add local automatic reply YCDriverAutoReply = 15, // v5.2.2 add driver automatic reply driver role YCLoctionUpdateVersionReply = 16, // v5.2.2 unknown message type reply [the message type is not supported. Please upgrade]}; typedef NSInteger SpeakType;
Request the chat list Interface Based on the session type, and process the data after the request is successful:
// IsRemote click the push column message if (response & [response [@ "ret_code"] integerValue] = 200) {NSArray * array = response [@ "result"]; id topVC = [[YCAppDelegate sharedDelegate] topViewController]; _ block NSString * orderID = nil; _ block NSString * dType = nil; [array enumerateObjectsUsingBlock: ^ (NSDictionary * result, NSUInteger idx, BOOL * stop) {NSString * type = [self controlMessageDispatch: result]; dType = type; // five hundred words omitted here} else {DLog (@ "response failed to poll data =%@, error =%@", response, error );}

If the request is successful when code = 200, all chat messages are retrieved from the array, and then each element in the array is saved by using the enumerateObjectsUsingBlock method. Each element is a chat message. Then, use controlMessageDispatch to obtain the Message Type (dType ):
typedef NS_ENUM(NSInteger, ClassType) {   OrderClass = 1,   ChatClass = 2,   UserClass = 3,};
The first is the order type message, the second is the chat type message, and the third is the account message. For order messages, determine the status based on the type and send different notifications. If the chat type is used, pass the result:
- (void)receiveChatMessage:(id)object
Method, and then there is a message Status field kChatRepeatState. If kChatRepeatState = 20, the read message is returned directly. If not, use content to initialize YCChatInfo:
NSDictionary *content = dic[@"content"];YCChatInfo *item;item = [[YCChatInfo alloc] initWithDictionary:content];
Then determine the ChatType. There are several types:
// Chat type enum ChatType {ChatText = 1, ChatImage = 2, ChatAudio = 3, ChatPOI = 4, ChatMix = 5, // The mixed content ChatCard = 6, // v5.2.2 card message ChatUpdateHint = 701 // v5.2.2 does not support type upgrade prompt}; typedef NSInteger ChatType;

If it is a voice message, You Need To asynchronously request to download the voice message. After the download is complete, the message is displayed on the interface, and the colleague sets the message to unread, and then stores it in the database. Then, return to the main thread to send the NotifactionName: the kChatMessageNotification notification chat interface receives chat information, displays the chat information, and stores it in the database:
[[NSNotificationCenter defaultCenter] postNotificationName:kChatMessageNotification                                                    object:nil                                                  userInfo:@{@"chatInfo" : chatInfo}];[self.chatStore insertChat:chatInfo];
There was a bug last time. After the chat message is duplicated, the voice message cannot be received because I inserted data into the new chat message first and then sent a notification, as a result, the display of chat messages on the interface is always unavailable.

If it is a text message, set the state to MessageRead read, send a Notifaction notification chat page, and save it to the database. If it is another message type, change content to "unsupported message type | your current version is too low, click upgrade client", and then send a notification to save it to the database.

For the third type of account message, the system displays a red dot and sends a Notifaction notification to the viewcontroller message center. After obtaining the dType
// First determine whether the message is pushed, and determine if (isRemote & [pushId isEqualToString: result [@ "id"]) {if (! OrderID & ([type isEqualToString: @ "new_chat"] | [type isEqualToString: @ "DRIVER_ARRIVE"] | [type isEqualToString: @ "exception_driver"] | [type isEqualToString: @ "SERVICE_DONE"]) {if ([type isEqualToString: @ "new_chat"]) {orderID = result [@ "content"] [@ "topic"];} else if (! [TopVC isKindOfClass: [YCSelectDriverViewController class] & ([type isEqualToString: @ "DRIVER_ARRIVE"] | [type isEqualToString: @ "exception_driver"] | [type isEqualToString: @ "SERVICE_DONE"]) {orderID = result [@ "content"] [@ "order_id"] ;}}}]; if (orderID) {if ([defavaluvalueforkey (kShowWelcome) boolValue]) {if (! [TopVC isKindOfClass: [YCWelcomeVC class]) {[[nsicationicationcenter defacenter center] postNotificationName: kRemotePushVC object: nil userInfo :@{ @ "orderID": orderID, @ "type ": dType}] ;}}

First, determine whether the message is pushed, and determine whether the push id of the click is entered, if the orderID does not exist and if the type is a new chat message or the driver has arrived, the driver takes over the ticket or the service ends, it enters the if judgment, and then judges whether the type is a chat, if the chat orderID is the topic field in the content, if it is not a new chat and the current top-level ViewController is not the YCSelectDriverViewController class and the type is the driver's arrival or the driver receives the ticket or the service ends, it enters the if judgment. orderID is the order_id field in the content.
If the orderID already exists, check whether the welcome page is displayed. Then, check whether the current top-level ViewController is not a welcome page class. Then, issue Notifaction and notify the view to jump to the specified ViewController page.
When a chat message is received, after a series of data processing, a notification is sent, and then the YCChatViewController receives a notification call-(void) receiveMessage :( NSNotification *) notification method:
-(Void) receiveMessage :( NSNotification *) notification {YCChatInfo * chatInfo = notification. userInfo [@ "chatInfo"]; // if the current session page is not entered for the message, NSString * string1 = [[NSString alloc] initWithFormat: @ "% @", chatInfo. orderID]; NSString * string2 = [[NSString alloc] initWithFormat: @ "% @", self. orderInfo. serverOrderId]; if (! [String1 isw.tostring: string2]) {return;} NSInteger messageID = chatInfo. messageID; YCChatStore * chatStore = [[YCChatStore alloc] init]; BOOL isNotRepeat = [chatStore selectDBwithMessageID: messageID]; if (! IsNotRepeat) {return;} [self insertRowToTableViewByIndexPath: chatInfo isSend: NO];}
The first sentence is to get the chat message content transmitted in the notification, and then compare the orderID in chatinfo with the orderID obtained through the interface for obtaining order details. If the orderID is inconsistent, return directly. If you go to the selectDBwithMessageID method in YCChatStore to check whether the database has the same messageID, if there is direct return, if not, insert the interface
- (NSIndexPath *)insertRowToTableViewByIndexPath:(YCChatInfo *)chatInfo isSend:(BOOL)isSend {    NSIndexPath *indexPath;    [self.chatArray addObject:chatInfo];        indexPath = [NSIndexPath indexPathForRow:[self.chatArray count] - 1                                   inSection:0];    void(^ScrollBlock)() = ^{        DLog(@"%d",indexPath.row);        [self.tableView scrollToRowAtIndexPath:indexPath                              atScrollPosition:UITableViewScrollPositionBottom                                      animated:YES];    };    [self.tableView insertRowsAtIndexPaths:@[indexPath]                          withRowAnimation:YCTableViewRowAnimationFromBottom                                completion:^{                                    if (isSend) {                                        ScrollBlock();                                    }    }];        if (!isSend) {        ScrollBlock();    }        return indexPath;}

-(Void) scrollToRowAtIndexPath :( NSIndexPath *) indexPath atScrollPosition :( UITableViewScrollPosition) scrollPosition animated :( BOOL) This method is to slide the first indexpath To the bottom of tableview,-(void) insertRowsAtIndexPaths :( NSArray *) indexPaths
WithRowAnimation :( YCTableViewRowAnimation) animation
Completion :( void (^) (void) animationCompletion
This is an animated effect during insertion.
Briefly introduces the names and functions of all model, view, and controller classes in the chat system:
MODEL:
YCChatInfo: defines all the fields used in the chat interface, chat-related enumeration information, and BOOL judgment of chat messages. YCChatStore: Mainly used to create tables, insert, delete, query, deduplication, and update chat data. YCChatRequest: encapsulates chat-related network requests. YCChatRecord: it is mainly encapsulation related to recording, including starting recording, ending recording, obtaining the recording duration, converting the audio format, and obtaining the audio path through SessionID. YCReceiveMessageCenter: similar to NotifactionCenter, it is a message center for chat message processing. All received chat messages and sent chat messages are processed by MessageCenter.
Views:
YCChatTableView: inherits the tableview class. it overwrites the insert animation of tableview, which is the insert animation for each new message. YCChatBaseCell: all cells in a chat inherit from this cell (text, voice, and in the future, images, geographic locations, etc) it mainly defines the Label, background image, profile picture, driver name, and loading of the chat time.
YCChatAudioCell: Voice chat cell, including play button, red dot prompt, recording time label
YCChatImageCell YCChatTextCell: Send text chat cell
YCHeadView: cell
YCRecordView: Click and hold the view in the chat interface.
YCOrderRecordView
YCPlayButton: Specifies the audio playback button.
YCChatDriverAcceptCardCell: A successfully reserved card is added in version 5.2.3.
YCChatJourneyStartCell: v5.2.3 new drivers are now on the go and drivers are on the cards
YCChatUpdatHintCell: the type is not supported. The upgrade prompt is displayed.

Controllers:
YCChatViewController: Main chat interface
YCChatMenuViewController: button on the right of the chat Yc#journeycardvc: Details page of the successful booking card YCChatMapVC: the map in the chat card
















Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.