SimpleSample-chat users-ios

Ask tech team
From QuickBlox Developers (API docs, code samples, SDK)
Jump to: navigation, search

Contents

Sources

Project homepage on GIT — https://github.com/QuickBlox/quickblox-ios-sdk/tree/master/sample-chat

Download ZIP - https://github.com/QuickBlox/quickblox-ios-sdk/archive/master.zip


Overview

This sample demonstrates how to work with QuickBlox Chat API.
It allows you to organise group Chat & 1 to 1 chat

It gives examples of how to:

  1. Organise chat between 2 users
  2. Organise group chat


Guide: Getting Started with Chat API

Get a QuickBlox account

http://admin.quickblox.com/register

Create applications in the Admin panel

http://admin.quickblox.com/apps/new

In addition, there is this helpful 5 minute guide.

Connect QuickBlox to your application

To get the information on how to connect to the QuickBlox.framework, please, refer to the IOS-how-to-connect-Quickblox-framework page.

Login to Chat

Note: In order to login to the chat please read the information about Chat login/password formation.

In order to use QuickBlox Chat APIs you must:

  • Create session & Sign In to QuickBlox OR just create session with user
  • Sign In to QuickBlox Chat

Please follow the lines below:

Create session with User & Sign In to QuickBlox Chat

// Create session with user
NSString *userLogin = @"chatUser1";
NSString *userPassword = @"chatUser1pass";
 
QBSessionParameters *parameters = [QBSessionParameters new];
parameters.userLogin = userLogin;
parameters.userPassword = userPassword;
 
[QBRequest createSessionWithExtendedParameters:parameters successBlock:^(QBResponse *response, QBASession *session) {
    // Sign In to QuickBlox Chat
    QBUUser *currentUser = [QBUUser user];
    currentUser.ID = session.userID; // your current user's ID
    currentUser.password = userPassword; // your current user's password   
 
    // set Chat delegate
    [QBChat instance].delegate = self;
 
    // login to Chat
    [[QBChat instance] loginWithUser:currentUser];
 
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"error: %@", response.error);
}];
 
 
#pragma mark -
#pragma mark QBChatDelegate
 
// Chat delegate
-(void) chatDidLogin{
    // You have successfully signed in to QuickBlox Chat
}
 
- (void)chatDidNotLogin{
 
}

Keep in mind that the QuickBlox Chat is a standard XMPP chat and you need to send presence periodically to remain available. Just create a timer that will send presence each 60 seconds:

[NSTimer scheduledTimerWithTimeInterval:60 target:[QBChat instance] selector:@selector(sendPresence) userInfo:nil repeats:YES];

Secure connection

To use secure Chat connection over TLS use next line of code:

[QBSettings useTLSForChat:YES];

Chat in background mode

As iOS doesn't provide 'true' background mode, we can't have a persistent Chat connection while iOS application is in background. The better way to handle correctly chat offline messages is to do 'Chat logout' when app goes to background and does 'Chat login' when app goes to foreground:

@implementation AppDelegate
 
// this is our AppDelegate class
 
- (void)applicationWillTerminate:(UIApplication *)application
{
    [[QBChat instance] logout];
}
 
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[QBChat instance] logout];
}
 
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // check here if a user was logged in to Chat and login him if YES
    // ...
    [[QBChat instance] loginWithUser:user];
}

Dialogs

QuickBlox provides a way to organise a chat dialogs page where you can show all user's current chat dialogs.

Dialogs can have next types:

  • 1-1 private dialog - a chat dialog between 2 users
  • Group dialog - a chat dialog between many users
  • Open group dialog - open chat dialog, any user can join and chat here.

Retrieve list of dialogs

Here is how typical screen with all your chats looks like:

Chat2.0 chatslist.png

Request Dialogs each time user logins to app, use Retrieve Dialogs request:

NSMutableDictionary *extendedRequest = [NSMutableDictionary new];
extendedRequest[@"limit"] = @(100);
//extendedRequest[@"skip"] = @(100);
 
[QBChat dialogsWithExtendedRequest:extendedRequest delegate:self];
 
 
#pragma mark -
#pragma mark QBActionStatusDelegate
 
- (void)completedWithResult:(Result *)result{
    if (result.success && [result isKindOfClass:[QBDialogsPagedResult class]]) {
        QBDialogsPagedResult *pagedResult = (QBDialogsPagedResult *)result;
        NSArray *dialogs = pagedResult.dialogs;
        NSLog(@"Dialogs: %@", dialogs);
    }
}

Create new dialog

According to REST API, Create a dialog query, you don't need to create a dialog for 1-1(private) chat - it will be created automatically with 1st chat message. But you can create it anyway if you need this for in your application.

Create new group chat dialog

When user would like to start a group chat - he should create a group chat dialog first.

Chat2.0 chatnew.png

User should choose other users to add them to a new group dialog. Also he should choose a name for new group chat:

QBChatDialog *chatDialog = [QBChatDialog new];
chatDialog.name = @"Chat with Bob, Sam, Garry";
chatDialog.occupantIDs = @[@(55), @(678), @(22)];
chatDialog.type = QBChatDialogTypeGroup;
 
[QBChat createDialog:chatDialog delegate:self];
 
 
#pragma mark -
#pragma mark QBActionStatusDelegate
 
- (void)completedWithResult:(Result *)result{
    if (result.success && [result isKindOfClass:[QBChatDialogResult class]]) {
        QBChatDialogResult *res = (QBChatDialogResult *)result;
        QBChatDialog *dialog = res.dialog;
        NSLog(@"Dialog: %@", res.dialog);
    }
}

To notify all occupants that you created a group chat we use chat notifications - it's simple chat message with extra parameters inside. These parameters used to separate chat notifications from regular text chat messages:

- (QBChatMessage *)createChatNotificationForGroupChatCreation:(QBDialog *)dialog
{
    // create message:
    QBChatMessage *inviteMessage = [QBChatMessage message];
    inviteMessage.text = @"optional text";
 
    NSMutableDictionary *customParams = [NSMutableDictionary new];
    customParams[@"xmpp_room_jid"] = dialog.roomJID;
    customParams[@"name"] = dialog.name;
    customParams[@"_id"] = dialog.ID;
    customParams[@"type"] = @(dialog.type);
    customParams[@"occupants_ids"] = [dialog.occupantIDs componentsJoinedByString:@","];
 
    // Add notification_type=1 to extra params when you created a group chat 
    //
    customParams[@"notification_type"] = @"1";
 
    inviteMessage.customParameters = customParams;
 
    return inviteMessage;
}
 
...
 
for (NSString *occupantID in dialog.occupantIDs) {
 
    QBChatMessage *inviteMessage = [self createChatNotificationForGroupChatCreation:dialog];
 
    NSTimeInterval timestamp = (unsigned long)[[NSDate date] timeIntervalSince1970];
    customParams[@"date_sent"] = @(timestamp);
 
    // send notification
    //
    inviteMessage.recipientID = [occupantID integerValue];
    [[QBChat instance] sendMessage:inviteMessage];
}

Create new 1-1(private) chat dialog

If you would like to create a private chat dialog too - use next snippets:

QBChatDialog *chatDialog = [QBChatDialog new];
chatDialog.type = QBChatDialogTypePrivate;
 
[QBChat createDialog:chatDialog delegate:self];
 
 
#pragma mark -
#pragma mark QBActionStatusDelegate
 
- (void)completedWithResult:(Result *)result{
    if (result.success && [result isKindOfClass:[QBChatDialogResult class]]) {
        QBChatDialogResult *res = (QBChatDialogResult *)result;
        QBChatDialog *dialog = res.dialog;
        NSLog(@"Dialog: %@", res.dialog);
    }
}

Update group dialog

User can update group chat dialog name, add new occupants or leave this group chat. To add more occupants use push operator. To leave group chat (remove yourself) - use pull all operator:

Chat2.0 groupchatdetails.png


NSMutableDictionary *extendedRequest = [NSMutableDictionary new];
extendedRequest[@"push[occupants_ids][]"] = @"378"; // Add user with ID 378
// extendedRequest[@"pull_all[occupants_ids][]"] = @"22"; // Remove yourself (user with ID 22)
extendedRequest[@"name"] = @"Team room";
 
[QBChat updateDialogWithID:@"53aac645535c12bd3b008a40" extendedRequest:extendedRequest delegate:self];
 
 
#pragma mark -
#pragma mark QBActionStatusDelegate
 
- (void)completedWithResult:(Result *)result{
    if (result.success && [result isKindOfClass:[QBChatDialogResult class]]) {
        QBChatDialogResult *res = (QBChatDialogResult *)result;
        QBChatDialog *dialog = res.dialog;
        NSLog(@"Dialog: %@", res.dialog);
    }
}

To notify all occupants that you updated a group chat we use chat notifications - it's simple chat message with extra parameters inside. These parameters used to separate chat notifications from regular text chat messages:

- (QBChatMessage *)createChatNotificationForGroupChatUpdate:(QBDialog *)dialog
{
    // create message:
    QBChatMessage *inviteMessage = [QBChatMessage message];
    inviteMessage.text = @"optional text";
 
    NSMutableDictionary *customParams = [NSMutableDictionary new];
    customParams[@"xmpp_room_jid"] = dialog.roomJID;
    customParams[@"name"] = dialog.name;
    customParams[@"_id"] = dialog.ID;
    customParams[@"type"] = @(dialog.type);
    customParams[@"occupants_ids"] = [dialog.occupantIDs componentsJoinedByString:@","];
 
    // Add notification_type=2 to extra params when you updated a group chat 
    //
    customParams[@"notification_type"] = @"2";
 
    inviteMessage.customParameters = customParams;
 
    return inviteMessage;
}
 
...
 
for (NSString *occupantID in dialog.occupantIDs) {
 
    QBChatMessage *inviteMessage = [self createChatNotificationForGroupChatUpdate:dialog];
 
    NSTimeInterval timestamp = (unsigned long)[[NSDate date] timeIntervalSince1970];
    customParams[@"date_sent"] = @(timestamp);
 
    // send notification
    //
    inviteMessage.recipientID = [occupantID integerValue];
    [[QBChat instance] sendMessage:inviteMessage];
}

Chat in dialog

Chat in 1-1 private dialog

To send a message in 1-1 chat - choose opponent's user ID and create a body of chat message.

1-1 private dialog contains your opponent's user ID in recipientID property.

[[QBChat instance] setDelegate:self];
 
...
 
QBChatDialog *privateChatDialog = ...;
 
QBChatMessage *message = [QBChatMessage message];
[message setText:@"Hey there"];
//
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"save_to_history"] = @YES;
[message setCustomParameters:params];
//
[message setRecipientID:privateCHatDialog.recipientID]; // ID of your opponent
//
[[QBChat instance] sendMessage:message];
 
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidReceiveMessage:(QBChatMessage *)message{
 
}

Chat in group dialog

Before start chating in a group dialog you should join this dialog.

QBChatDialog *groupChatDialog = ...;
 
// Use a newly created dialog and its 'roomJID' field to join a room
QBChatRoom *groupChatRoom = [groupChatDialog chatRoom];
self.thisGroupChatRoom = groupChat;
[self.thisGroupChatRoom joinRoomWithHistoryAttribute:@{@"maxstanzas": @"0"}];
 
...
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatRoomDidEnter:(QBChatRoom *)room{
   // joined here, now you can send and receive chat messages within this group dialog
}

Now you can send and receive messages:

QBChatMessage *message = [QBChatMessage message];
[message setText:@"Hey there"];
//
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"save_to_history"] = @YES;
[message setCustomParameters:params];
//
[message setRecipientID:305]; // ID of your opponent
//
[[QBChat instance] sendChatMessage:message toRoom:self.thisGroupChatRoom];
 
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatRoomDidReceiveMessage:(QBChatMessage *)message fromRoomJID:(NSString *)roomJID{
 
}


Get online users

You can request online users in group chat dialog

[[QBChat instance] requestRoomOnlineUsers:self.thisGroupChatRoom];
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatRoomDidReceiveListOfOnlineUsers:(NSArray *)users roomJID:(NSString *)roomJID{
    NSLog(@"Room did receive list of online users %@, room JID: %@",users, roomJID);
}


And you also can handle online users in real time:

#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatRoomDidChangeOnlineUsers:(NSArray *)onlineUsers roomJID:(NSString *)roomJID
{
    NSLog(@"Room did change online users: %@, room JID: %@",onlineUsers, roomJID);
}


Leave group chat dialog
[[QBChat instance] leaveRoom:self.thisGroupChatRoom];
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatRoomDidLeaveRoomWithJID:(NSString *)roomJID
{
    NSLog(@"Room did leave with JID %@", roomJID);
}

Send and receive a message with attachment

Send attachment

It's possible to add attachments to message: for example, image, audio file or video file. We don't have any restrictions here - you can attach any type of file.

To send a message with attachments you should use the same way as you send regular message with text, but add to it an attachment object. Attachment can be:

  • A file in Content module: iOS example
  • A file in Custom Objects module: iOS example
  • Can be an url to any file in Internet


To send a message with attachment you should upload a file to Content module, Custom Objects module using sample above or use an url to any file in Internet. Then you should incorporate an ID to file to message.

For example, we use Content module to store attachments. Next snippets show how to upload a file to Content module and send it as an attach:

// Upload a file to the Content module
NSData *image = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image45" ofType:@"png"]];
//
[QBContent TUploadFile:image fileName:@"image45" contentType:@"image/png" isPublic:NO delegate:self];
 
#pragma mark -
#pragma mark QBActionStatusDelegate
 
- (void)completedWithResult:(Result *)result{
 
    // success result
    if(result.success){
        // Upload file result
        if([result isKindOfClass:QBCFileUploadTaskResult.class]){
 
            // get uploaded file ID
            QBCFileUploadTaskResult *res = (QBCFileUploadTaskResult *)result;
            NSUInteger uploadedFileID = res.uploadedBlob.ID;
 
            // Create chat message with attach
            //
            QBChatMessage *message = [QBChatMessage message];
 
            ...
 
            QBChatAttachment *attachment = QBChatAttachment.new;
            attachment.type = @"image";
            attachment.ID = [NSString stringWithFormat:@"%d", uploadedFileID]; // use 'ID' property to store an ID of a file in Content or CustomObjects modules
           //  attachment.url = @"http://mysite.com/avatar.png"; // use 'url' property to store an url to file in Internet
           [message setAttachments:@[attachment]];
    }else{
        NSLog(@"Errors=%@", result.errors);
    }
}

Receive attachment

For example we use Content module to store attachments. Next snippets allow to receive a message with an attachment and download it:

#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidReceiveMessage:(QBChatMessage *)message{
    for(QBChatAttachment *attachment in message.attachments){
        // download file by ID
        [QBContent TDownloadFileWithBlobID:[attachment.ID integerValue] delegate:self];
    }
}
 
#pragma mark -
#pragma mark QBActionStatusDelegate
 
- (void)completedWithResult:(Result *)result{
    // Download file result
    if(result.success && [result isKindOfClass:QBCFileDownloadTaskResult.class]){
        // extract image
        QBCFileDownloadTaskResult *res = (QBCFileDownloadTaskResult *)result;
        UIImage *image = [UIImage imageWithData:res.file];
    }else{
        NSLog(@"Errors=%@", result.errors);
    }
}

Use custom parameters in a message

You can use custom parameters for the messages you send in the chat, for example to send some additional info or to send control messages:

// send message
QBChatMessage *message = [QBChatMessage message];
message.recipientID = 546; // opponent's id
[message setCustomParameters:@{@"age": @(25)}];
 
[[QBChat instance] sendMessage:message];


Chat history

You can choose a way to save chat message to history or not. If you decided to store - you should add save_to_history parameter to message:

QBChatMessage *message = [QBChatMessage message];
...
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"save_to_history"] = @YES;
[message setCustomParameters:params];
...


List chat messages

If you decided to use save_to_history parameter - all chat messages will be stored to history and user can request a chat history for particular dialog.

Chat2.0 listmessages.png

To get a chat history for particular dialog use next request:

NSMutableDictionary *extendedRequest = [NSMutableDictionary new];
extendedRequest[@"limit"] = @(100);
 
[QBChat messagesWithDialogID:@"53b413f3e4b077ddd43e85e0" extendedRequest:extendedRequest delegate:self];
 
 
#pragma mark - QBActionStatusDelegate
#pragma mark 
 
- (void)completedWithResult:(Result *)result{
    if (result.success && [result isKindOfClass:QBChatHistoryMessageResult.class]) {
        QBChatHistoryMessageResult *res = (QBChatHistoryMessageResult *)result;
        NSArray *messages = res.messages;
        NSLog(@"Messages: %@", messages);
    }
}



Push notifications for offline users

QuickBlox provides a way to setup automatic push notifications for the offline users. It means if your opponent is offline while you writing a message - he can automatically receive push notification.

Look at Admin panel and read how to setup automatic push notifications in Alerts section.


Dashboard

QuickBlox dashboard provide a way to view and manage all dialogs for your application. Go to admin panel, Chat module. Read more info here.


Contact list

Contact list mode

In traditional IM applications, the "buddy" system is rather straightforward. User A sends a request to become "friends" with user B. User B accepts the friend request. And now user A and B appear in each other's roster. By default this SDK provides this mode.


But, alternatively, you can use twitter like logic. User A sends a presence subscription request to user B. Think about this more like following on twitter. User A is requesting permission to receive presence information from user B (following their presence). User B can accept this request, but may not be interested in receiving presence info from user B. Again, this is more like twitter following, but with the addition of required permission.So when user B accepts the request, this *only* means that user A will receive presence from user B. It does *not* mean that user B will receive presence from user A. Again, twitter-style, user A is now "following" user B. In diagram form, presence is flowing like this:

 A <-- B


Now, if B also wants to receive presence from user A, then user B must request this permission. And furthermore, user A must accept the request. Just because B has granted A permission to receive presence, doesn't mean that B gets a free pass to receive presence from A.

To enable twitter like logic use use next code:

[QBChat instance].useMutualSubscriptionForContactList = NO;

To check subscription state of particular contact use subscriptionState property of QBContactListItem class. It can be the next:

  • QBPresenseSubscriptionStateNone - the user does not have a subscription to the contact's presence information, and the contact does not have a subscription to the user's presence information
  • QBPresenseSubscriptionStateTo - the user has a subscription to the contact's presence information, but the contact does not have a subscription to the user's presence information
  • QBPresenseSubscriptionStateFrom - the contact has a subscription to the user's presence information, but the user does not have a subscription to the contact's presence information
  • QBPresenseSubscriptionStateBoth - both the user and the contact have subscriptions to each other's presence information

Access to the Contact list

To access contact list you can use the contactList property in QBChat class:

[QBChat instance].contactList.contacts // array of accepted contacts
 
//
 
[QBChat instance].contactList.pendingApproval // array of pending requests

You can also track contact list updates in real time by using delegates:

#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatContactListDidChange:(QBContactList *)contactList{
}
 
- (void)chatDidReceiveContactItemActivity:(NSUInteger)userID isOnline:(BOOL)isOnline status:(NSString *)status{
}

Adding/Removing users

To add users to the contact list just use the method below:

[[QBChat instance] addUserToContactListRequest:218650]; // user ID

This user will receive the request to be added to the contact list:

#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidReceiveContactAddRequestFromUser:(NSUInteger)userID{
    // do something
}

To confirm the request:

[[QBChat instance] confirmAddContactRequest:218650]; // user ID

To reject the request:

[[QBChat instance] rejectAddContactRequest:218650]; // user ID

To remove a previously added user from the contact list:

[[QBChat instance] removeUserFromContactList:218651]; // user ID

Custom status

A client MAY provide detailed status information to his contacts by using the status parameter in presence:

[[QBChat instance] sendPresenceWithStatus:@"I shall return!"];



Privacy list

Privacy list API allows to enable or disable communication with other users in a chat. Privacy list API also enables a user to create, modify, or delete its privacy lists, define a default list.

Retrieve privacy lists names

User can have multiple privacy lists. To get a list of all your privacy lists' names use next request:

[[QBChat instance] retrievePrivacyListNames];
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidReceivePrivacyListNames:(NSArray *)listNames{
    NSLog(@"chatDidReceivePrivacyListNames: %@", listNames);
}
 
- (void)chatDidNotReceivePrivacyListNamesDueToError:(id)error{
    NSLog(@"chatDidNotReceivePrivacyListNamesDueToError: %@", error);
}

Create a privacy list or edit existing list

A privacy list must have at least one element in order to create it. If no elements specified then the list with given name will be deleted. When you want to update a privacy list, it must include all of the desired items (i.e., not a "delta").

QBPrivacyItem *item = [[QBPrivacyItem alloc] initWithType:USER_ID valueForType:1022685 action:DENY];
QBPrivacyList *list = [[QBPrivacyList alloc] initWithName:@"public" items:@[item]];
 
[[QBChat instance] setPrivacyList:list];
 
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidSetPrivacyListWithName:(NSString *)name{
    NSLog(@"chatDidSetPrivacyListWithName %@", name);
}
 
- (void)chatDidNotSetPrivacyListWithName:(NSString *)name error:(id)error{
    NSLog(@"chatDidNotSetPrivacyListWithName: %@ due to error:%@", name, error);
}

QBPrivacyItem class takes 3 arguments:

  • type - always use USER_ID
  • valueForType - ID of a user to apply an action
  • action - can be ALLOW/DENY.

Activate a privacy list

User can have multiple privacy lists, but active can be only one. In order to activate rules from a privacy list you must activate it by setting as default.

[[QBChat instance] setDefaultPrivacyListWithName:@"public"];
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidSetDefaultPrivacyListWithName:(NSString *)name{
    NSLog(@"chatDidSetDefaultPrivacyListWithName %@", name);
}
 
- (void)chatDidNotSetDefaultPrivacyListWithName:(NSString *)name error:(id)error{
    NSLog(@"chatDidNotSetDefaultPrivacyListWithName: %@ due to error:%@", name, error);
}

Retrieve a privacy list

[[QBChat instance] retrievePrivacyListWithName:@"public"];
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidReceivePrivacyList:(QBPrivacyList *)privacyList{
    NSLog(@"chatDidReceivePrivacyList: %@", privacyList);
}
 
- (void)chatDidNotReceivePrivacyListWithName:(NSString *)name error:(id)error{
    NSLog(@"chatDidNotReceivePrivacyListWithName: %@ due to error:%@", name, error);
}

Delete existing privacy list

To delete a list you can call a method below or you can edit a list and set items to nil.

[[QBChat instance] removePrivacyListWithName:@"public"];
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidRemovedPrivacyListWithName:(NSString *)name{
    NSLog(@"chatDidRemovedPrivacyListWithName %@", name);
}
 
- (void)chatDidNotSetPrivacyListWithName:(NSString *)name error:(id)error{
    NSLog(@"chatDidNotSetPrivacyListWithName: %@ due to error:%@", name, error);
}

Blocked user attempts to communicate with user

Blocked entities will be receiving an error when try to chat with a user:

QBChatMessage *message = [QBChatMessage message];
[message setText:@"example message"];
[message setRecipientID:1022637];
[[QBChat instance] sendMessage:message];
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidNotSendMessage:(QBChatMessage *)message error:(NSError *)error{
    NSLog(@"chatDidNotSendMessage: %@ \nerror:%@", message, error);
}
NSLog output:
chatDidNotSendMessage: 
 ID: 1408614930.907598 
 senderID: 1022637 
 recipientID: 1022685 
 datetime: 2014-08-21 09:55:31 +0000 
 text: example message 
 attachments: (null)
 delayed: 0 
 senderNick: (null) 
error:Error Domain=com.quickblox.chat Code=503 "Service not available." UserInfo=0xa393fd0 {NSLocalizedDescription=Service not available.}

Typing status

Many instant messaging systems include notifications about the state of one's conversation partner in a one-to-one chat (or, sometimes, in a many-to-many chat). In essence, chat state notifications can be thought of as a form of chat-specific presence.

This section describes how to integrate chat states notifications into your application.

Here is a list of common Chat State Notifications:

  1. typing: The user is composing a message. The user is actively interacting with a message input interface specific to this chat session (e.g., by typing in the input area of a chat window)
  2. paused: The user had been composing but now has stopped. The user was composing but has not interacted with the message input interface for a short period of time (e.g., 30 seconds)

With QuickBlox you can use all these chat status notifications.

Here is an example of how to implement the typing notification.

To produce this notification we should implement a UITextFieldDelegate delegate in the application:

@interface ChatViewController : UIViewController <UITextFieldDelegate>
 
@property (nonatomic, assign) IBOutlet UITextField *textField;
 
...
 
@implementation ChatViewController
 
#pragma mark
#pragma mark UITextFieldDelegate
 
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
 
    // send 'is typing' notification to opponent
    [[QBChat instance] sendUserIsTypingToUserWithID:1022725]; // 1022725 is an opponent's user id
 
    return YES;
}
 
- (void)textFieldDidEndEditing:(UITextField *)textField{
    // finish typing
    [[QBChat instance] sendUserStopTypingToUserWithID:1022725]; // 1022725 is an opponent's user id
}

On the opponent's side we can track this notification and update the UI:

@interface ChatViewController : UIViewController <QBChatDelegate>
 
...
 
@implementation ChatViewController
 
#pragma mark
#pragma mark QBChatDelegate
 
- (void)chatDidReceiveUserIsTypingFromUserWithID:(NSUInteger)userID{
    // opponent is typing - update UI
}
- (void)chatDidReceiveUserStopTypingFromUserWithID:(NSUInteger)userID{
    // opponent has stopped typing - update UI
}


Delivered status

SDK automatically manages delivery notifications if you use marked messages.

Term 'marked' relies to messages that have automatic delivery control.

To mark a message as 'markable' use [QBChatMessage markableMessage] class method to create a message instance.

For such messages you will receive delivery confirmations.

QBChatMessage *message = [QBChatMessage markableMessage];
[message setText:@"Hi there!"];
[message setRecipientID:1022725];
[[QBChat instance] sendMessage:message];
 
// save packet ID of current message
NSString *packetID = message.ID;
 
#pragma mark -
#pragma mark QBChatDelegate
 
- (void)chatDidDeliverMessageWithPacketID:(NSString *)packetID{
    NSLog(@"chatDidDeliverMessageWithPacketID: %@", packetID);
}

Comments

Feel free to comment on this page using the form below.

blog comments powered by Disqus