Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 100 additions & 62 deletions calls/ios/ringing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ The ringing flow involves two SDKs working together:

```mermaid
sequenceDiagram
participant Caller
participant ChatSDK
participant Receiver
participant CallsSDK
Caller->>ChatSDK: initiateCall()
ChatSDK->>Receiver: onIncomingCallReceived
Receiver->>ChatSDK: acceptCall()
ChatSDK-->>Caller: onOutgoingCallAccepted
Caller->>CallsSDK: joinSession()
Receiver->>CallsSDK: joinSession()
participant Caller
participant ChatSDK
participant Receiver
participant CallsSDK

Caller->>ChatSDK: initiateCall()
ChatSDK->>Receiver: onIncomingCallReceived
Receiver->>ChatSDK: acceptCall()
ChatSDK-->>Caller: onOutgoingCallAccepted
Caller->>CallsSDK: joinSession()
Receiver->>CallsSDK: joinSession()
```

## Initiate a Call
Expand Down Expand Up @@ -58,12 +58,9 @@ NSString *receiverID = @"USER_ID";
CometChatReceiverType receiverType = CometChatReceiverTypeUser;
CometChatCallType callType = CometChatCallTypeVideo;

Call *call = [[Call alloc] initWithReceiverId:receiverID
callType:callType
receiverType:receiverType];
Call *call = [[Call alloc] initWithReceiverId:receiverID callType:callType receiverType:receiverType];

[CometChat initiateCallWithCall:call
onSuccess:^(Call * call) {
[CometChat initiateCallWithCall:call onSuccess:^(Call * call) {
NSLog(@"Call initiated: %@", call.sessionID);
// Show outgoing call UI
} onError:^(CometChatException * error) {
Expand All @@ -79,6 +76,59 @@ Call *call = [[Call alloc] initWithReceiverId:receiverID
| `receiverType` | ReceiverType | `.user` or `.group` |
| `callType` | CallType | `.video` or `.audio` |

## Call Timeout

By default, if the receiver does not answer within **45 seconds**, the call is automatically marked as `unanswered` and the caller receives the `onOutgoingCallRejected` callback. You can customize this duration by passing a `timeout` parameter (in seconds) when initiating the call.

<Tabs>
<Tab title="Swift">
```swift
let receiverID = "USER_ID"
let receiverType: CometChat.ReceiverType = .user
let callType: CometChat.CallType = .video

let call = Call(receiverId: receiverID, callType: callType, receiverType: receiverType)

// Set a custom timeout of 30 seconds
CometChat.initiateCall(call: call, timeout: 30, onSuccess: { call in
print("Call initiated: \(call?.sessionID ?? "")")
}, onError: { error in
print("Call initiation failed: \(error?.errorDescription ?? "")")
})
```
</Tab>
<Tab title="Objective-C">
```objectivec
NSString *receiverID = @"USER_ID";
CometChatReceiverType receiverType = CometChatReceiverTypeUser;
CometChatCallType callType = CometChatCallTypeVideo;

Call *call = [[Call alloc] initWithReceiverId:receiverID callType:callType receiverType:receiverType];

// Set a custom timeout of 30 seconds
[CometChat initiateCallWithCall:call timeout:30 onSuccess:^(Call * call) {
NSLog(@"Call initiated: %@", call.sessionID);
} onError:^(CometChatException * error) {
NSLog(@"Call initiation failed: %@", error.errorDescription);
}];
```
</Tab>
</Tabs>

| Parameter | Type | Description |
|-----------|------|-------------|
| `call` | Call | The call object with receiver and call type details |
| `timeout` | Double | Time in seconds to wait before marking the call as unanswered. Defaults to `45`. Non-integer values are truncated (e.g., `30.7` becomes `30`). Values ≤ 0 fall back to the default `45` seconds. |

When the timeout expires without the call being accepted, the SDK automatically:
1. Sends an `unanswered` call status to the server.
2. Triggers the `onOutgoingCallRejected` callback on the caller's side with the call status set to `.unanswered`.
3. Cleans up the call session.

<Note>
If the call is accepted, rejected, or cancelled before the timeout expires, the timer is automatically stopped and the timeout has no effect.
</Note>

## Listen for Incoming Calls

Register a call listener to receive incoming call notifications:
Expand All @@ -92,7 +142,7 @@ CometChat.addCallListener(listenerID, self)

// Implement CometChatCallDelegate
extension CallViewController: CometChatCallDelegate {

func onIncomingCallReceived(incomingCall: Call?, error: CometChatException?) {
guard let call = incomingCall else { return }
print("Incoming call from: \(call.callInitiator?.name ?? "")")
Expand Down Expand Up @@ -128,32 +178,27 @@ NSString *listenerID = @"UNIQUE_LISTENER_ID";
[CometChat addCallListener:listenerID delegate:self];

// Implement CometChatCallDelegate
- (void)onIncomingCallReceivedWithIncomingCall:(Call *)incomingCall
error:(CometChatException *)error {
- (void)onIncomingCallReceivedWithIncomingCall:(Call *)incomingCall error:(CometChatException *)error {
NSLog(@"Incoming call from: %@", incomingCall.callInitiator.name);
// Show incoming call UI with accept/reject options
}

- (void)onOutgoingCallAcceptedWithAcceptedCall:(Call *)acceptedCall
error:(CometChatException *)error {
- (void)onOutgoingCallAcceptedWithAcceptedCall:(Call *)acceptedCall error:(CometChatException *)error {
NSLog(@"Call accepted, joining session...");
[self joinCallSessionWithSessionId:acceptedCall.sessionID];
}

- (void)onOutgoingCallRejectedWithRejectedCall:(Call *)rejectedCall
error:(CometChatException *)error {
- (void)onOutgoingCallRejectedWithRejectedCall:(Call *)rejectedCall error:(CometChatException *)error {
NSLog(@"Call rejected");
// Dismiss outgoing call UI
}

- (void)onIncomingCallCancelledWithCancelledCall:(Call *)cancelledCall
error:(CometChatException *)error {
- (void)onIncomingCallCancelledWithCancelledCall:(Call *)cancelledCall error:(CometChatException *)error {
NSLog(@"Incoming call cancelled");
// Dismiss incoming call UI
}

- (void)onCallEndedMessageReceivedWithEndedCall:(Call *)endedCall
error:(CometChatException *)error {
- (void)onCallEndedMessageReceivedWithEndedCall:(Call *)endedCall error:(CometChatException *)error {
NSLog(@"Call ended");
}
```
Expand All @@ -164,12 +209,13 @@ NSString *listenerID = @"UNIQUE_LISTENER_ID";
|----------|-------------|
| `onIncomingCallReceived` | A new incoming call is received |
| `onOutgoingCallAccepted` | The receiver accepted your outgoing call |
| `onOutgoingCallRejected` | The receiver rejected your outgoing call |
| `onOutgoingCallRejected` | The receiver rejected your outgoing call, or the call timed out as unanswered |
| `onIncomingCallCancelled` | The caller cancelled the incoming call |
| `onCallEndedMessageReceived` | The call has ended |

<Warning>
Remember to remove the call listener when it's no longer needed to prevent memory leaks:

```swift
CometChat.removeCallListener(listenerID)
```
Expand All @@ -195,8 +241,7 @@ func acceptIncomingCall(sessionId: String) {
<Tab title="Objective-C">
```objectivec
- (void)acceptIncomingCallWithSessionId:(NSString *)sessionId {
[CometChat acceptCallWithSessionID:sessionId
onSuccess:^(Call * call) {
[CometChat acceptCallWithSessionID:sessionId onSuccess:^(Call * call) {
NSLog(@"Call accepted");
[self joinCallSessionWithSessionId:call.sessionID];
} onError:^(CometChatException * error) {
Expand Down Expand Up @@ -229,9 +274,7 @@ func rejectIncomingCall(sessionId: String) {
<Tab title="Objective-C">
```objectivec
- (void)rejectIncomingCallWithSessionId:(NSString *)sessionId {
[CometChat rejectCallWithSessionID:sessionId
status:CometChatCallStatusRejected
onSuccess:^(Call * call) {
[CometChat rejectCallWithSessionID:sessionId status:CometChatCallStatusRejected onSuccess:^(Call * call) {
NSLog(@"Call rejected");
// Dismiss incoming call UI
} onError:^(CometChatException * error) {
Expand Down Expand Up @@ -264,9 +307,7 @@ func cancelOutgoingCall(sessionId: String) {
<Tab title="Objective-C">
```objectivec
- (void)cancelOutgoingCallWithSessionId:(NSString *)sessionId {
[CometChat rejectCallWithSessionID:sessionId
status:CometChatCallStatusCancelled
onSuccess:^(Call * call) {
[CometChat rejectCallWithSessionID:sessionId status:CometChatCallStatusCancelled onSuccess:^(Call * call) {
NSLog(@"Call cancelled");
// Dismiss outgoing call UI
} onError:^(CometChatException * error) {
Expand Down Expand Up @@ -311,13 +352,13 @@ func joinCallSession(sessionId: String) {
build];

[CometChatCalls joinSessionWithSessionID:sessionId
callSetting:sessionSettings
container:self.callViewContainer
onSuccess:^(NSString * message) {
NSLog(@"Joined call session");
} onError:^(CometChatCallException * error) {
NSLog(@"Failed to join: %@", error.errorDescription);
}];
callSetting:sessionSettings
container:self.callViewContainer
onSuccess:^(NSString * message) {
NSLog(@"Joined call session");
} onError:^(CometChatCallException * error) {
NSLog(@"Failed to join: %@", error.errorDescription);
}];
}
```
</Tab>
Expand All @@ -333,15 +374,15 @@ Always call `CometChat.endCall()` when ending a call. This notifies the other pa

```mermaid
sequenceDiagram
participant User
participant CallsSDK
participant ChatSDK
participant OtherParticipant
User->>CallsSDK: leaveSession()
User->>ChatSDK: endCall(sessionId)
ChatSDK->>OtherParticipant: onCallEndedMessageReceived
OtherParticipant->>CallsSDK: leaveSession()
participant User
participant CallsSDK
participant ChatSDK
participant OtherParticipant

User->>CallsSDK: leaveSession()
User->>ChatSDK: endCall(sessionId)
ChatSDK->>OtherParticipant: onCallEndedMessageReceived
OtherParticipant->>CallsSDK: leaveSession()
```

When using the default call UI, listen for the end call button click using `ButtonClickListener` and call `endCall()`:
Expand All @@ -350,18 +391,17 @@ When using the default call UI, listen for the end call button click using `Butt
<Tab title="Swift">
```swift
class CallViewController: UIViewController, ButtonClickListener {

var currentSessionId: String = ""

override func viewDidLoad() {
super.viewDidLoad()
CallSession.shared.addButtonClickListener(self)
}

func onLeaveSessionButtonClicked() {
endCall(sessionId: currentSessionId)
}

func endCall(sessionId: String) {
// 1. Leave the call session (Calls SDK)
CallSession.shared.leaveSession()
Expand All @@ -375,7 +415,7 @@ class CallViewController: UIViewController, ButtonClickListener {
self.navigationController?.popViewController(animated: true)
})
}

// Other ButtonClickListener callbacks...
}
```
Expand All @@ -402,8 +442,7 @@ class CallViewController: UIViewController, ButtonClickListener {
[[CallSession shared] leaveSession];

// 2. Notify other participants (Chat SDK)
[CometChat endCallWithSessionID:sessionId
onSuccess:^(Call * call) {
[CometChat endCallWithSessionID:sessionId onSuccess:^(Call * call) {
NSLog(@"Call ended successfully");
[self.navigationController popViewControllerAnimated:YES];
} onError:^(CometChatException * error) {
Expand All @@ -430,8 +469,7 @@ func onCallEndedMessageReceived(endedCall: Call?, error: CometChatException?) {
</Tab>
<Tab title="Objective-C">
```objectivec
- (void)onCallEndedMessageReceivedWithEndedCall:(Call *)endedCall
error:(CometChatException *)error {
- (void)onCallEndedMessageReceivedWithEndedCall:(Call *)endedCall error:(CometChatException *)error {
[[CallSession shared] leaveSession];
[self.navigationController popViewControllerAnimated:YES];
}
Expand All @@ -450,4 +488,4 @@ func onCallEndedMessageReceived(endedCall: Call?, error: CometChatException?) {
| `cancelled` | Caller cancelled before receiver answered |
| `ended` | Call ended normally |
| `missed` | Receiver didn't answer in time |
| `unanswered` | Call was not answered |
| `unanswered` | Call was not answered within the timeout duration |
Binary file added images/compact-message-composer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading