logo
On this page

Call invitation


Overview

ZEGO Instant Messaging (ZIM) SDK provides the call invitation feature that supports full service procedure control. For example, the feature allows a caller to send a call invitation to a called user and allows the called user to accept or refuse the invitation. In this case, the caller and the called user can be offline. A call invitation can be in a common mode or an advanced mode.

In common mode, a user can initiate, cancel, accept, and reject a call invitation, and does not respond to a call invitation within the specified timeout period. On this basis, in advanced mode, a user can invite a new user during the call, and quit and terminate the call.

The call invitation feature provides only basic capabilities for service procedure control. The service requirements for using this feature must be manually implemented. For example, the feature is commonly used in a chat tool for initiating a voice call invitation or a video call invitation.

User states

ZIMCallUserState specifies the state of a user in each call invitation procedure. This section describes how a user state changes, and the relationship among a state, an operation, and a callback.

State changes

The following figure shows how a user state changes in an entire call invitation process from call initiation to call termination.

StateDescriptionTriggering eventApplicable mode
InvitingBeing invited.The user is being invited.
  • Common mode
  • Advanced mode
AcceptedInvitation accepted.
  • A user initiates a call invitation.
  • A user accepts a call invitation.
RejectedInvitation rejected.A user rejects a call invitation.
CanceledInvitation canceled.
  • A user cancels a call invitation.
  • The called user does not respond to the invitation. The caller gets offline and the heartbeat times out.
ReceivedInvitation received.
  • An online user receives a call invitation.
  • An offline user gets online within the specified timeout period.
TimeoutInvitation times out.The called user fails to respond to the invitation within the specified timeout period.
QuitQuit the call.A user in the call quit the call.
  • Advanced mode
UnknownUnknownContact ZEGOCLOUD technical support.

States and corresponding operations and callbacks

In a call invitation process, the call state of a user determines whether the user can call a specific operation or listen to a specific event.

  • The following table describes the correspondence between a call state and an operation.
callInvitecallCancelcallAcceptcallRejectcallingInvitecallQuitcallEnd
InvitingA user can call this operation when the user is in a call, regardless of the call state of the user.A user can call this operation when no response is given to a call invitation after the user initiates the call invitation, regardless of the user state.✔️✔️
Accepted✔️✔️✔️
Rejected
Canceled
Received✔️✔️
Timeout
Quit
Unknown
  • The following table describes the correspondence between a call state and a callback.
onCallInvitationReceivedonCallInvitationTimeoutonCallInvitationCancelledonCallInvitationEndedonCallUserStateChanged
Inviting✔️✔️✔️✔️✔️
Accepted✔️✔️
Rejected
Cancelled
Received✔️✔️✔️
Timeout
Quit✔️
Unknown

Common mode

In common mode, the lifecycle of a call invitation ends after all invitees respond to the invitation. To be specific, a call invitation is terminated after all invitees accept or refuse the invitation, or the invitation times out. The following example shows that a client A initiates a call invitation to a client B in common mode.

1. Listen to the state changes of call invitation users

You can invoke the callUserStateChanged callback to listen to the state changes of an invitee.

Untitled
// Listen to the state changes of users related to the call invitation.
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    for (ZIMCallUserInfo *userInfo in info.callUserList) {
        // The userID whose user state has changed.
        NSString *userID = userInfo.userID;
        
        // The latest user state of the user.
        ZIMCallUserState state = userInfo.state;
        
        // Transmitted field, consistent with the extended data content carried by the user when calling the accept, reject, or exit interface.
        NSString *extendedData = userInfo.extendedData;
    }
}
1
Copied!

2. Initiate a call invitation

The client A initiates a call invitation to the client B. The following figure shows the corresponding flowchart.

  1. Client A registers the callInvitationCreated callback interface to receive notifications that a call invitation has been created; Client B registers the callInvitationReceived callback interface to receive invitation notifications from client A.
  2. Client A initiates a call invitation by calling the callInviteWithInvitees interface. After receiving the invitation information, client B can choose to Accept or Reject.
Note

If the client B is offline, the following two cases are involved:

  • Send a call invitation to an online user:
Untitled
// Send a call invitation to an online user. 
NSArray<NSString *> * invitees = @[@"421234"]; // List of invitees

ZIMCallInviteConfig *callInviteConfig = [[ZIMCallInviteConfig alloc] init];
// Set the timeout for the invitation
callInviteConfig.timeout = 200;

// (Optional) Fill in when you need to initiate a call invitation to an offline user and push related offline notifications
ZIMPushConfig *pushConfig = [[ZIMPushConfig alloc] init];
pushConfig.title = @"your title";
pushConfig.content = @"your content";
pushConfig.payload = @"your payload";
callInviteConfig.pushConfig = pushConfig;

[zim callInviteWithInvitees:invitees config:callInviteConfig callback:^(NSString *callID, ZIMCallInvitationSentInfo *info,ZIMError *errorInfo){
    // Fill in the callback after sending the call invitation here
    // The callID here is the ID generated internally by the SDK after the user initiates the call, which is used to uniquely identify a call invitation; the caller cancels the call and the invitee accepts/rejects the call, and this callID will be used.
}];
1
Copied!
  • The invitation initiator receives a notification that the call invitation has been created.
Untitled
/**  Invitation initiator receives notification that a call invitation has been created.*/
- (void)zim:(ZIM *)zim
    callInvitationCreated:(ZIMCallInvitationCreatedInfo *)info
                callID:(NSString *)callID{
    // Fill in the callback notification that the call invitation initiator received a successful invitation creation.
}
1
Copied!
  • The callback notification after the invitee receives the invitation
Untitled
// Callback notification when the invitee receives the invitation.
- (void)zim:(ZIM *)zim
    callInvitationReceived:(ZIMCallInvitationReceivedInfo *)info
                    callID:(NSString *)callID{
    // Fill in the callback notification when the invitee receives the invitation.
} 
1
Copied!

3. Cancel a call invitation

The client A sends a call invitation to the client B and then cancels the call invitation. The following figure shows the corresponding flowchart.

  1. After the client A initiates a call invitation, the client A can call the callCancelWithInvitees operation to cancel the call invitation.
Note

After a call invitation is successfully initiated and before it times out, if no callee accepts, and if the caller actively logs out or disconnects due to a heartbeat timeout, the call invitation will also be canceled.

  1. After the call invitation is canceled, the client B can receive a notification that is returned by the callInvitationCancelled callback.
  • Cancel a call invitation.
Untitled
// Cancel a call invitation.
NSArray<NSString *> * invitees = @[@"421234"];   // The IDs of the invitees.
NSString* callid = @"12352435";  // callid
ZIMCallCancelConfig *callCancelConfig = [[ZIMCallCancelConfig alloc] init]; 

[zim callCancelWithInvitees:invitees callID:self.callID config:callCancelConfig callback:^(NSString * _Nonnull callID, NSArray<NSString *> * _Nonnull errorInvitees, ZIMError * _Nonnull errorInfo) {
    //Fill in the callback after canceling the call invitation.
}];

1
Copied!
  • The callback notification received by the invitee after the call invitation is canceled.
Untitled
// The callback notification after the invitee receives the canceled invitation.
- (void)zim:(ZIM *)zim
callInvitationCancelled:(ZIMCallInvitationCancelledInfo *)info
callID:(NSString *)callID{
// Fill in the callback notification after the invitee receives the canceled invitation.
}

1
Copied!

4. Accept a call invitation

The client B receives a call invitation from the client A and then accepts the call invitation. The following figure shows the corresponding flowchart.

  1. After the client B receives a call invitation from the client A, the client B can call the callAcceptWithCallID operation to accept the call invitation.
  2. After the client B accepts the call invitation, the client A can receive a notification that is returned by the callUserStateChanged callback. If multiple users are involved in the call invitation, all involved users can receive the notification returned by this callback.
  • Accept a call invitation.
Untitled
// Accept a call invitation.
NSString* callid = @"12352435";  // callid
ZIMCallAcceptConfig*callAcceptConfig = [[ZIMCallAcceptConfig alloc] init]; 
[zim callAcceptWithCallID:self.callID config:callAcceptConfig callback:^(NSString * _Nonnull callID, ZIMError * _Nonnull errorInfo) {
    // Fill in the callback after accepting the call invitation here.
}];

[zim callAcceptWithCallID:callid config:callAcceptConfig  callback:^(ZIMError *errorInfo){
    // Fill in the callback after accepting the call invitation here.
}];
1
Copied!
  • The callback notification returned after the invitee accepts the call invitation.
Untitled
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
// All users with user state of "Inviting", "Accepted" and "Received" can receive notifications that a user has accepted a call invitation here.
}
1
Copied!

5. Reject a call invitation

The client B receives a call invitation from the client A and then rejects the call invitation. The following figure shows the corresponding flowchart.

  1. After the client B receives a call invitation from the client A, the client B can call the callRejectWithCallID operation to reject the call invitation.
  2. After the client B rejects the call invitation, the client A can receive a notification that is returned by the callUserStateChanged callback.
  • Reject a call invitation.
Untitled
// Reject a call invitation.
NSString* callid = @"12352435";  // callid
ZIMCallRejectConfig* callRejectConfig = [[ZIMCallRejectConfig alloc] init]; 

[zim callRejectWithCallID:self.callID config:callRejectConfig callback:^(NSString * _Nonnull callID, ZIMError * _Nonnull errorInfo) {
    // Fill in the callback after rejecting the call invitation.
}];

1
Copied!
  • The callback notification returned after the invitee rejects the call invitation.
Untitled
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
// All users with user state of "Inviting", "Accepted" and "Received" can receive notifications that a user has rejected a call invitation here.
}
1
Copied!

6. A call invitation times out

The client B receives a call invitation from the client A, but does not respond to the call invitation within the timeout period. The following figure shows the corresponding flowchart.

  1. The client A, namely, the inviter, can invoke the callUserStateChanged callback to receive a notification indicating that the call invitation times out because the client B does not respond to the invitation. If multiple users are involved in the call invitation, all involved users can receive the notification returned by this callback.
  2. The client B, namely, the invitee, can invoke the callInvitationTimeout callback to receive a notification indicating that the call invitation times out because the client B itself does not respond to the invitation.
  • The callback notification received by the "inviter" after the invitee responds for a timeout.
Untitled
// The callback notification received by the "invitee" after the invitee responds for a timeout.
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
// All users with the user state of "Inviting", "Accepted" and "Received" can receive notifications of users accepting call invitations here.
}
1
Copied!
  • The callback notification received by the "invitee" after the invitee responds for a timeout.
Untitled
// The callback notification received by the "invitee" after the invitee responds for a timeout.
-(void)zim:(ZIM *)zim callInvitationTimeout:(NSString *)callID {
// Fill in the callback notification received by the "invitee" after the invitee responds for a timeout, the timeout unit is: seconds.
}
1
Copied!

Advanced mode

You can initiate a call invitation in advanced mode in a call invitation scenario involving a plurality of users, such as a multi-invitee call invitation scenario.

After a call invitation is initiated in advanced mode, the lifecycle of the call invitation ends when a user calls the callEnd operation to terminate the call. Before the call is terminated, a user in the call can invite a new user or quit the call.

Initiate a call invitation in advanced mode

To initiate a call invitation in advanced mode, you must specify the mode when you call the callInviteWithInvitees operation.

Untitled
// Send a call invitation to an online user in advanced mode.

NSArray<NSString *> * invitees = @[@"421234"];  // The IDs of the invitees.

ZIMCallInviteConfig *callInviteConfig = [[ZIMCallInviteConfig alloc] init]; 
// mode is the call invitation mode, ZIMCallInvitationModeAdvanced indicates the advanced mode.
callInviteConfig.mode = ZIMCallInvitationModeAdvanced;
// Set the invitation timeout
callInviteConfig.timeout = 200;

// (Optional) Fill in when you need to initiate a call invitation to an offline user and push related offline notifications.
ZIMPushConfig *pushConfig = [[ZIMPushConfig alloc] init];
pushConfig.title = @"your title";
pushConfig.content = @"your content";
pushConfig.payload = @"your payload";
callInviteConfig.pushConfig = pushConfig;

[zim callInviteWithInvitees:invitees config:callInviteConfig callback:^(NSString *callID, ZIMCallInvitationSentInfo *info,ZIMError *errorInfo){
// Fill in the callback after sending the call invitation here.
// The callID here is the ID generated internally by the SDK after the user initiates the call, which is used to uniquely identify a call invitation; this callID will be used when the initiator cancels the call and the invitee accepts/rejects the call.
}];
1
Copied!
Note

The advanced mode is the same as the common mode in call invitation cancellation, acceptance, rejection, and timeout. The only difference between the two modes lies in call invitation initiation.

Invite a user during a call

After a call invitation is initiated in advanced mode, a user in the Accepted state can call the callingInviteWithInvitees operation to invite a new user. Note that a maximum of 10 users(including the invitation initiator) are allowed in a call.

  • Invite a user during a call
Untitled
// Invite a user during a call
ZIMCallingInviteConfig *config = [[ZIMCallingInviteConfig alloc] init];

// callID is obtained by creating a callback for advanced call invitation.
[[ZIM getInstance] callingInviteWithInvitees:@[@"invitees"] callID:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallingInvitationSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
if(errorInfo.code != ZIMErrorCodeSuccess){
        // Handle according to the error code table on the official website.
        return;
}
    // Business logic after successful invitation.
}];

1
Copied!
  • Call members receive notifications that they are inviting other users.
Untitled
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
// All users whose user state is "Inviting" and "Accepted" can receive notifications that they are calling to invite a user here.
}

1
Copied!

Actively join a call or switch devices

After implementing the advanced mode call invitation, the callJoin interface can be called in the following two situations:

  • A user who has not joined the call wishes to join the call.
  • After a multi-terminal login user uses device A to initiate or accept an invitation, he or she wants to make other devices the new primary device.
Note
  • The main device refers to the device that actively calls the interface to initiate, accept or join the call to participate in the call.
  • Only the main device can detect changes in call invitations, and other devices can only obtain the data in the call invitations by querying the call invitation list.

For the scenario where the user outside the call joins successfully, the user's state will flow to accepted. At this time, all users in the call will receive the notification callback of callUserStateChanged

For the scenario of switching devices, other users in the call will not be aware of it.

Untitled
// Actively join a call or switch devices.

ZIMCallJoinConfig *callJoinConfig = [[ZIMCallJoinConfig alloc] init];
callJoinConfig.extendedData = @"extendedData";
[[ZIM getInstance] callJoin:@"callID" config:callJoinConfig callback:^(NSString * _Nonnull callID, ZIMCallJoinSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
          
    }else{
        // Handle according to the error code table on the official website.
    }
}];
1
Copied!

Quit a call

After a call invitation is initiated in advanced mode, a user in the Accepted state can call the callQuit operation to quit the call. After the user quits the call, the state of the user is changed to quit. Then, the user and other users who still stay in the call receive a notification returned by the callUserStateChanged callback.

Untitled
// Quit a call.
ZIMCallQuitConfig *config = [[ZIMCallQuitConfig alloc] init];

[[ZIM getInstance] callQuit:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallQuitSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
        // Business logic after successful exit.                                                    
    }else{
        // Handle errors according to the official website error code table.
    }
}];
1
Copied!
  • The users in the call receive a notification indicating that a user quits the call.
Untitled
-(void)zim:(ZIM *)zim callUserStateChanged:(ZIMCallUserStateChangeInfo *)info callID:(nonnull NSString *)callID{
    // The user who quits the call and other users that are in the `Inviting`, `Received`, and `Accept` states receive a notification indicating that a user quits the call.      
}
1
Copied!

Terminate a call

After a call invitation is initiated in advanced mode, a user in the Accepted state can call the callEnd operation to terminate the call. Subsequently, states of all users remain unchanged, and the call state is changed to end. The users in the Iniviting, Accepted, and Received states receive a notification returned by the callInvitationEnded callback.

  • Terminate a call.
Untitled
// Terminate a call.
ZIMCallEndConfig *config = [[ZIMCallEndConfig alloc] init];

[[ZIM getInstance] callEnd:self.callID config:config callback:^(NSString * _Nonnull callID, ZIMCallEndedSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {
    if(errorInfo.code == ZIMErrorCodeSuccess){
        // Business logic after successful completion.
    }else{
        // Handle errors according to the official website error code table.
    }
}];
1
Copied!
  • The users in the call receive a notification indicating that the call is terminated.
Untitled
- (void)zim:(ZIM *)zim callInvitationEnded:(ZIMCallInvitationEndedInfo *)info callID:(NSString *)callID{
    // All users whose state is “Inviting”, “Accepted” and “Received” will receive a notification that the call has ended.
}
1
Copied!

What's more

Check whether the invitation has been delivered

If you want to let the online users in the invitation know whether other users have received the invitation, so as to implement related business logic, please change enableNotReceivedCheck in ZIMCallInviteConfig to YES when initiating a call invitation, so as to start checking whether the invitation has been delivered.

Untitled
ZIMCallInviteConfig *inviteConfig = [[ZIMCallInviteConfig alloc] init];
//Enable not yet delivered detection
inviteConfig.enableNotReceivedCheck = YES;

//Initiate call invitation related code
1
Copied!

After the caller initiates a call invitation, if the called party does not receive this invitation within 5 seconds (you can contact ZEGOCLOUD Technical Support to adjust the interval to 3 seconds or 4 seconds) due to network disconnection, offline, etc.:

  • If the called party client uses the ZIM SDK version 2.14.0 or later, its user state will flow to ZIMCallUserStateNotYetReceived, indicating that the invitation has not yet been delivered. At this time, the business logic can be implemented to display UI prompts such as "This user may be offline and cannot receive call invitations temporarily" to online users in the call invitation.
  • If the called client uses ZIM SDK version 2.14.0 or earlier, its user state remains ZIMCallUserStateInviting. If this state remains for more than 5 seconds, the above business logic can also be implemented.
Note

Please refer to listen to the state changes of call invitation users for more information.

Afterwards, if the called user goes online and accepts the invitation before the invitation times out, the user state of the member will flow to ZIMCallUserStateReceived.

Query the list of call invitations

A user can call the queryCallInvitationListWithConfig operation to query the list of call invitations related to the user. The maximum entries for a single query is 100, and any number exceeding 100 will be processed as 100.

Untitled
// Query the list of call invitations.

ZIMCallInvitationQueryConfig *config = [[ZIMCallInvitationQueryConfig alloc] init];
// Query 20 call invitation data at a time
// If count exceeds 100, treat it as 100
config.count = 20;
// For the first query, fill in 0 for nextFlag, which means starting from the latest call invitation (the one with the latest creation time)
config.nextFlag = 0;
[[ZIM getInstance] queryCallInvitationListWithConfig:config callback:^(NSArray<ZIMCallInfo *> * _Nonnull callList, long long nextFlag, ZIMError * _Nonnull errorInfo) {
if(errorInfo.code != ZIMErrorCodeSuccess){
// Handle the error according to the error code table on the official website
return;
}
if(nextFlag != 0){
// If the nextFlag returned by callback is not 0, it means that all call invitation information has not been queried. The next time you query, you can pass in the nextFlag returned by callback to continue querying the remaining call invitation information
config.nextFlag = nextFlag;
}
}];
1
Copied!

Previous

Reply to a message

Next

Get the conversion list