QuickBlox Documentation

QuickBlox provides powerful Chat API and SDK to add real-time messaging and video calls to your web and mobile apps. Learn how to integrate QuickBlox across multiple platforms and devices. Check out our detailed guides to make integration easy and fast.

Chat

Learn how to enable chat functionality for your app.

Chat API is built on top of real-time (XMPP) protocol. In order to use it, you need to setup real-time connection with QuickBlox Chat server and use it to exchange data. By default real-time Chat works over secure TLS connection.

Connect to Chat server

To connect to Chat server use the code snippet below.

QBSettings.autoReconnectEnabled = true
QBSettings.reconnectTimerInterval = 5
QBSettings.carbonsEnabled = true
QBSettings.keepAliveInterval = 20
QBSettings.streamManagementSendMessageTimeout = 0
QBSettings.networkIndicatorManagerEnabled = false

let currentUser = QBUUser()
currentUser.ID = 56
currentUser.password = "chatUserPass"
QBChat.instance.connect(withUserID: currentUser.id, password: currentUser.password, completion: { (error) in
    
})
[QBSettings setAutoReconnectEnabled:YES];
[QBSettings setReconnectTimerInterval:5];
[QBSettings setCarbonsEnabled:YES];
[QBSettings setKeepAliveInterval:20];
[QBSettings setStreamManagementSendMessageTimeout:0];
[QBSettings setNetworkIndicatorManagerEnabled:NO];

QBUUser *currentUser = [QBUUser user];
currentUser.ID = 56
currentUser.password = @"chatUserPass";
[QBChat.instance connectWithUserID:currentUser.ID password:currentUser.password completion:^(NSError * _Nullable error) {
    
}];
ParametersDescription
autoReconnectEnablediOS SDK reconnects automatically to the Chat server when the connection to the server is lost. Default: false.
reconnectTimerIntervalA reconnect timer can optionally be used to attempt a reconnect periodically. Set in seconds. Default: 5.
carbonsEnabledMessage carbons allow for real-time message syncing between devices. Default: false.
keepAliveIntervalKeep-alive option for a socket connection. Keep-alive is the option allowing to detect a stale connection. Set in seconds. Default: 20.
streamManagementSendMessageTimeoutThe timeout value for stream management. Set in seconds. If this parameter is greater than 0, then it is applied, otherwise, it is not applied. Default: 0.
networkIndicatorManagerEnabledA boolean value indicating whether the manager is enabled. If true, the manager will change status bar network activity indicator according to network operation notifications it receives. Default: false.

Use QBChatDelegate to handle different connection states.

class YourClass : NSObject {
    QBChat.instance.addDelegate(self)
}
// MARK: QBChatDelegate
extension YourClass : QBChatDelegate {
    func chatDidConnect() {
    }
    func chatDidReconnect() {
    }
    func chatDidDisconnectWithError(_ error: Error) {
    }
    func chatDidNotConnectWithError(_ error: Error) {
    }
}
@interface YourClass () <QBChatDelegate>
@end

@implementation YourClass
- (instancetype)init {
    self = [super init];
    if (self) {
        [QBChat.instance addDelegate:self];
    }
    return self;
}
// MARK: QBChatDelegate
- (void)chatDidConnect {
}
- (void)chatDidReconnect {
}
- (void)chatDidDisconnectWithError:(NSError *)error {
}
- (void)chatDidNotConnectWithError:(NSError *)error {
}
- (void)chatDidFailWithStreamError:(NSError *)error {
}

@end;

Disconnect from Chat server

Disconnect from the Chat server using the snippet below.

QBChat.instance.disconnect { (error) in
    
}
[QBChat.instance disconnectWithCompletionBlock:^(NSError * _Nullable error) {
    
}];

Autoreconnect to Chat

The SDK reconnects automatically when the connection to the Chat server is lost. There is a way to disable it and then manage it manually.

QBSettings.autoReconnectEnabled = false
QBSettings.autoReconnectEnabled = NO;

Chat in background

To handle chat offline messages correctly do disconnect() when an app goes to background and connect() when an app goes to the foreground.

class AppDelegate: UIResponder, UIApplicationDelegate {
    // ...
    func applicationWillTerminate(_ application: UIApplication) {
        QBChat.instance.disconnect { (error) in
        }
    }
    func applicationDidEnterBackground(_ application: UIApplication) {
        QBChat.instance.disconnect { (error) in
        }
    }
    func applicationWillEnterForeground(_ application: UIApplication) {
        QBChat.instance.connect(withUserID: currentUser.ID, password: currentUser.password) { (error) in
        }
    }
    // ...
}
@implementation AppDelegate
// ...
- (void)applicationWillTerminate:(UIApplication *)application {
    [QBChat.instance disconnectWithCompletionBlock:^(NSError * _Nullable error) {
    }];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
    [QBChat.instance disconnectWithCompletionBlock:^(NSError * _Nullable error) {
    }];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
    [QBChat.instance connectWithUserID:currentUser.ID password:currentUser.password completion:^(NSError * _Nullable error) {
    }];
}
// ...

Dialogs

All chats between users are organized in dialogs. There are 3 types of dialogs:

  • 1-1 dialog - a conversation between 2 users.
  • group dialog - a conversation between the specified list of users.
  • public dialog - an open conversation. Any user from your app can subscribe to it.

You need to create a new dialog and then use it to chat with other users. You also can obtain a list of your existing dialogs.

Create new dialog

Create 1-1 dialog

You need to pass private as a dialog type and ID of an opponent you want to create a chat with.

let dialog = QBChatDialog(dialogID: nil, type: .private)
dialog.occupantIDs = [34]
QBRequest.createDialog(dialog, successBlock: { (response, createdDialog) in

}, errorBlock: { (response) in
    
})
QBChatDialog *dialog = [[QBChatDialog alloc] initWithDialogID:nil type:QBChatDialogTypePrivate];
dialog.occupantIDs = @[@34]; // an ID of opponent
[QBRequest createDialog:dialog successBlock:^(QBResponse * _Nonnull response, QBChatDialog * _Nonnull createdDialog) {
        
} errorBlock:^(QBResponse * _Nonnull response) {
        
}];

Create group dialog

You need to pass QuickBlox DialogType.GROUP as a type and IDs of opponents, you want to create a chat with.

let chatDialog = QBChatDialog(dialogID: nil, type: .group)
chatDialog.name = "New group dialog"
chatDialog.occupantIDs = [34, 45, 55]
        
QBRequest.createDialog(chatDialog, successBlock: { (response, dialog) in
    dialog.join(completionBlock: { (error) in  
    })
}, errorBlock: { (response) in
    
})
QBChatDialog *chatDialog = [[QBChatDialog alloc] initWithDialogID:nil type:QBChatDialogTypeGroup];
chatDialog.name = @"Group dialog name";
chatDialog.occupantIDs = @[@34, @45, @55];

[QBRequest createDialog:chatDialog successBlock:^(QBResponse * _Nonnull response, QBChatDialog * _Nonnull dialog) {
    [dialog joinWithCompletionBlock:^(NSError * _Nullable error) {
        
    }];
} errorBlock:^(QBResponse * _Nonnull response) {

}];

Create public dialog

It's possible to create a public dialog, so any user from your application can subscribe to it. There is no a list with occupants, this dialog is just open for everybody. You need to specify public as a dialog type within the QBChatDialog instance.

let dialog = QBChatDialog(dialogID: nil, type: .public)
dialog.name = "Public dialog name"
dialog.dialogDescription = "Public dialog description"
// dialog.photo = "...";
    
QBRequest.createDialog(chatDialog, successBlock: { (response, dialog) in
    dialog.join(completionBlock: { (error) in  
    })                                             
}, errorBlock: { (response) in
    
})
QBChatDialog *dialog = [[QBChatDialog alloc] initWithDialogID:nil type:QBChatDialogTypePublicGroup];
dialog.name = @"Public dialog name";
dialog.dialogDescription = @"Public dialog description";
// dialog.photo = @"...";
    
[QBRequest createDialog:chatDialog successBlock:^(QBResponse * _Nonnull response, QBChatDialog * _Nonnull dialog) {
    [dialog joinWithCompletionBlock:^(NSError * _Nullable error) {
        
    }];
} errorBlock:^(QBResponse * _Nonnull response) {

}]

Retrieve list of dialogs

It's common to request all your conversations on every app login.

QBRequest.dialogs(for: QBResponsePage(limit: 50, skip: 100), extendedRequest: nil, successBlock: { (response, dialogs, dialogsUsersIDs, page) in

}, errorBlock: { (response) in
    
})
[QBRequest dialogsForPage:[QBResponsePage responsePageWithLimit:50 skip:100] extendedRequest:nil successBlock:^( response, dialogs, dialogsUsersIDs, page) {
        
} errorBlock:^(QBResponse * _Nonnull response) {
       
}];

It will return all your 1-1 dialogs, group dialog, and public dialogs you are subscribed to.

If you want to retrieve only conversations updated after some specific date time, you can pass the filter. For example, you can apply gt filter to updated_at and id fields using requestBuilder. This is useful if you cache conversations somehow and do not want to obtain the whole list of your conversations on every app start. You can use the other filters:

  • lt (Less Than operator)
  • lte (Less Than or Equal to ...)
  • gt (Greater Than operator)
  • gte (Greater Than or Equal to ...)
  • eq (Equals to ...)
  • ne (Not Equal to ...)
  • in (Contained IN array ...)
  • nin (Not contained IN array)
  • all (ALL contained IN array)
  • ctn (Contains ...)

Update dialog

Update a group dialog name, description or photo using update() method.

chatDialog.name = "New dialog name"
chatDialog.dialogDescription = "New dialog description"
chatDialog.photo = "https://new_photo_url" // or it can be an ID to some file in Storage module
    
QBRequest.update(chatDialog, successBlock: { (response, updatedDialog) in

}, errorBlock: { (response) in
    
})
dialog.name = @"New dialog name";
dialog.dialogDescription = @"New dialog description";
dialog.photo = @"https://new_photo_url"; // or it can be an ID to some file in Storage module

[QBRequest updateDialog:dialog successBlock:^(QBResponse * _Nonnull response, QBChatDialog * _Nonnull updatedDialog) {

} errorBlock:^(QBResponse * _Nonnull response) {

}];

❗️

Important note

Only group dialog owner can remove other users from a group dialog.

Add/Remove occupants

You can add/remove occupants in group and public dialogs.

let pushOccupantsIDs = [10056, 75432].map({ $0.stringValue })
chatDialog.pushOccupantsIDs = pushOccupantsIDs
QBRequest.update(chatDialog, successBlock: { (response, updatedDialog) in

}, errorBlock: { (response) in
    
})
dialog.pushOccupantsIDs = @[@"10056", @"75432"];
[QBRequest updateDialog:dialog successBlock:^(QBResponse * _Nonnull response, QBChatDialog * _Nonnull updatedDialog) {

} errorBlock:^(QBResponse * _Nonnull response) {

}];

❗️

Important note

Only group dialog owner can remove other users from a group dialog.

Remove dialog

The following snippet is used to delete a conversation.

QBRequest.deleteDialogs(withIDs: Set<String>(["5356c64ab35c12bd3b108a41", "d256c64ab35c12bd3b108bc5"]), forAllUsers: false, successBlock: { (deletedObjectsIDs, notFoundObjectsIDs, wrongPermissionsObjectsIDs) in
    
}, errorBlock: { (response) in
    
})
[QBRequest deleteDialogsWithIDs:[NSSet setWithArray:@[@"5356c64ab35c12bd3b108a41", @"d256c64ab35c12bd3b108bc5"]] forAllUsers:NO successBlock:^( deletedObjectsIDs, notFoundObjectsIDs, wrongPermissionsObjectsIDs) {
    
} errorBlock:^(QBResponse * _Nonnull response) {

}];

🚧

Note

This request will remove this conversation for a current user, but other users will be still able to chat there. The forceDelete parameter is used to completely remove the dialog. Only group chat owner can remove the group dialog. You can also delete multiple conversations in a single request.

Chat history

Every chat conversation stores its chat history that you can retrieve.

let page = QBResponsePage(limit: 50, skip: 100)
let extendedRequest = ["sort_desc": "date_sent", "mark_as_read": "0"]
QBRequest.messages(withDialogID: "5356c64ab35c12bd3b108a41", extendedRequest: extendedRequest, for: page, successBlock: { (response, messages, page) in

}, errorBlock: { (response) in
    
})
QBResponsePage *responsePage = [QBResponsePage responsePageWithLimit:50 skip:0];
NSDictionary *extReq = @{@"sort_desc": @"date_sent", @"mark_as_read": @"0"};
[QBRequest messagesWithDialogID:@"5356c64ab35c12bd3b108a41" extendedRequest:extReq forPage:responsePage successBlock:^(QBResponse *response, NSArray *messages, QBResponsePage *page) {

} errorBlock:^(QBResponse *response) {
                     
}];

If you want to retrieve chat messages using pagination by date or filtering, you can use filters. For example, you can apply gt or lt filters using extendedRequest.

🚧

Note

All retrieved chat messages will be marked as read after the request. If you decide not to mark chat messages as read, then add the following parameter to your extendedRequest -@{@"mark_as_read" : @"0"};

Send/Receive chat messages

1-1 dialog

To send a message to 1-1 dialog use the code snippet below.

let message = QBChatMessage()
message.text = "How are you today?"
message.customParameters["save_to_history"] = true
    
let privateDialog = ...
privateDialog.send(message) { (error) in
    
}
QBChatMessage *message = [[QBChatMessage alloc] init];
message.text = @"How are you today?";
message.customParameters[@"save_to_history"] = @"1";
    
QBChatDialog *privateDialog = ...;
[privateDialog sendMessage:message completionBlock:^(NSError * _Nullable error) {
    
}];

📘

Note

Make sure to specify the save_to_history field. This field is read by the server, and, consequently, the message is stored in the history. If the save_to_history is not specified, the message is no longer saved on the server.

Group/public dialog

Join group/public dialog

Before you start chatting in a group/public dialog, you need to join it by calling join() method.

let groupDialog = ...
groupDialog.join { (error) in
    
}
QBChatDialog *groupDialog = ...;
[groupDialog joinWithCompletionBlock:^(NSError * _Nullable error) {
    
}];

Then you are able to send/receive messages.

let message = QBChatMessage()
message.text = "How are you today?"
message.customParameters["save_to_history"] = true
    
let groupDialog = ...
groupDialog.send(message) { (error) in
    
}
    
//MARK: ChatDelegate   
func chatDidReceive(_ message: QBChatMessage) {
    
}
QBChatMessage *message = [[QBChatMessage alloc] init];
message.text = @"How are you today?";
message.customParameters[@"save_to_history"] = @"1";
    
QBChatDialog *groupDialog = ...;
[groupDialog sendMessage:message completionBlock:^(NSError * _Nullable error) {
    
}];
    
//MARK: QBChatDelegate
- (void)chatDidReceiveMessage:(QBChatMessage *)message {
    
}

📘

Note

Make sure to specify the save_to_history field. This field is read by the server, and, consequently, the message is stored in the history. If the save_to_history is not specified, the message is no longer saved on the server.

Leave group/public dialog

You can leave the group/public dialog by calling groupDialog.leave() method.

let groupDialog = ...
groupDialog.leave { (error) in
    
}
QBChatDialog *groupDialog = ...;
[groupDialog leaveWithCompletionBlock:^(NSError * _Nullable error) {
    
}];

Unread messages count

To get a number unread messages in a particular dialog, use the code snippet below.

let unreadMessagesCount = dialog.unreadMessagesCount
NSUInteger unreadMessagesCount = chatDialog.unreadMessagesCount;

You can also retrieve the total number of unread messages using the totalUnreadMessageCountForDialogs() method . It returns the total count of unread messages for all dialogs of the user in totalUnreadCount. It also returns unread messages count for dialogs with IDs in dialogsDictionary if any dialogIDs are specified.

let dialogIDs: Set<String> = ["8b23aa4f5d0b0be0900041aa", "1c23aa4f5d0b0be0900041ad"]
QBRequest.totalUnreadMessageCountForDialogs(withIDs: dialogIDs, successBlock: { ( response, totalUnreadCount, dialogsDictionary) in
    
}, errorBlock: { (response) in
    
})
[QBRequest totalUnreadMessageCountForDialogsWithIDs:[NSSet setWithArray:@[@"8b23aa4f5d0b0be0900041aa", @"1c23aa4f5d0b0be0900041ad"]]
successBlock:^(QBResponse * _Nonnull response, NSUInteger count, NSDictionary<NSString *,id> * _Nonnull dialogs) {
    
} errorBlock:^(QBResponse * _Nonnull response) {
    
}];
ParametersDescription
dialogIDsIDs of dialogs.
- If dialogIDs are not specified, the total number of unread messages for all dialogs of the user will be returned.
- If dialogIDs are specified, the total number of unread messages for the specified dialogs will be returned. Also, the total number of unread messages for all dialogs of the user will be returned.

Updated 17 days ago


What's Next

Advanced

Chat


Learn how to enable chat functionality for your app.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.