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.

Before you begin

  1. Visit our Key Concepts page to get an overall understanding of the most important QuickBlox concepts.
  2. Register a QuickBlox account. This is a matter of a few minutes and you will be able to use this account to build your apps.
  3. Configure QuickBlox SDK for your app. Check out our Setup page for more details.
  4. Create a user session to be able to use QuickBlox functionality. See our Authentication page to learn how to do it.

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) {
    
}];

Parameters

Description

autoReconnectEnabled

iOS SDK reconnects automatically to the Chat server when the connection to the server is lost. Default: false.

reconnectTimerInterval

A reconnect timer can optionally be used to attempt a reconnect periodically. Set in seconds. Default: 5.

carbonsEnabled

Message carbons allow for real-time message syncing between devices. Default: false.

keepAliveInterval

Keep-alive option for a socket connection. Keep-alive is the option allowing to detect a stale connection. Set in seconds. Default: 20.

streamManagementSendMessageTimeout

The 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.

networkIndicatorManagerEnabled

A 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 set the save_to_history as true to save the message on the server. If the save_to_history is set as false, the message won't be 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 set the save_to_history as true to save the message on the server. If the save_to_history is set as false, the message won't be 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) {
    
}];

Parameters

Description

dialogIDs

IDs 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.

Ping user

QuickBlox SDK can send application-level pings to a user. As a result, you can check if the user is connected to the Chat server.

let userId = 221809
let timeout = 20.0
QBChat.instance.pingUser(withID: userId, timeout: timeout) { (timeInterval, success) in
    // time interval of ping and whether it was successful
}
NSUInteger userId = 221809;
NSTimeInterval timeout = 20.0;
[QBChat.instance pingUserWithID:userId timeout:timeout completion:^(NSTimeInterval timeInterval, BOOL success) {
    // time interval of ping and whether it was successful
}];

Parameters

Required

Description

userId

yes

ID of the user.

timeout

no

Ping timeout. To control how much time it takes to respond to a ping, you should set a ping timeout. If the response wasn't received within the specified time frame, then the error callback is called. Default: 30 seconds.

As a result, a completion block with timeInterval and success parameters is called.

Parameters

Required

Description

timeInterval

yes

A double parameter. Indicates how long it took to ping in seconds.

success

yes

A boolean parameter. Indicates whether the ping was successful. If the sucess=1, the ping is successful (the user is connected to the Chat). If sucess=0, the ping isn't successful.

Ping server

QuickBlox SDK can send application-level pings to a server. As a result, you can check if there is a connection with the Chat server.

let timeout = 20.0
QBChat.instance.pingServer(withTimeout: timeout) { (timeInterval, success) in
    // time interval of ping and whether it was successful
}
NSTimeInterval timeout = 20.0;
[QBChat.instance pingServerWithTimeout:timeout completion:^(NSTimeInterval timeInterval, BOOL success) {
    // time interval of ping and whether it was successful
}];

Parameters

Required

Description

timeout

no

Ping timeout. To control how much time it takes to respond to a ping, you should set a ping timeout. If the response wasn't received within the specified time frame, then the error callback is called. Default: 30 seconds.

As a result, a completion block with timeInterval and success parameters is called.

Parameters

Required

Description

timeInterval

yes

A double parameter. Indicates how long did it took to ping in seconds.

success

yes

A boolean parameter. Indicates whether the ping was successful. If the sucess=1, the ping was successful. If sucess=0, the ping wasn't successful.

Updated 3 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.