> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-agent-native-development.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Standalone Calling

> CometChat Calling SDK v4 - Legacy Release - Standalone Calling for iOS

<Warning>
  **You're reading the legacy documentation for Calling SDK v4 (iOS).**

  Follow this page only if your app is on **v4.x**. If you're using v5, see the [**Calling SDK v5 documentation**](/calls/ios/overview) instead.

  Ready to move off v4? Follow the [v4 → v5 migration guide](/calls/ios/migration-guide-v5).
</Warning>

## Overview

This section demonstrates how to implement calling functionality using only the CometChat Calls SDK, without requiring the Chat SDK. This is ideal for applications that need video/audio calling capabilities without the full chat infrastructure.

<Note>
  Before you begin, ensure you have completed the [Calls SDK setup](/calls/v4/ios/setup).
</Note>

## User Authentication

To start a call session, you need a user auth token. Since this implementation doesn't use the Chat SDK, you'll need to obtain the auth token via the CometChat REST API.

<Note>
  To understand user authentication in CometChat, see the [User Auth](/fundamentals/user-auth) documentation.
</Note>

You can obtain the auth token using one of these REST API endpoints:

* [Create Auth Token](/rest-api/auth-tokens/create) — Creates a new auth token for a user
* [Get Auth Token](/rest-api/auth-tokens/get) — Retrieves an existing auth token

<Note>
  For testing or POC purposes, you can create an auth token directly from the [CometChat Dashboard](https://app.cometchat.com). Navigate to **Users & Groups → Users**, select a user, and click **+ Create Auth Token**.
</Note>

Store the auth token securely in your application for use when generating call tokens.

## Generate Call Token

A call token is required for secure access to a call session. Each token is unique to a specific session and user combination, ensuring that only authorized users can join the call.

Use the `generateToken()` method to create a call token:

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    var callToken: GenerateToken?

    let sessionId = "UNIQUE_SESSION_ID" // Generate a unique session ID
    let userAuthToken = "USER_AUTH_TOKEN" // Obtained from REST API

    CometChatCalls.generateToken(authToken: userAuthToken as NSString, sessionID: sessionId) { token in
        self.callToken = token
    } onError: { error in
        print("Token generation failed: \(String(describing: error?.errorDescription))")
    }
    ```
  </Tab>
</Tabs>

| Parameter | Description |
| - | - |
| `sessionId` | A unique session ID for the call. Generate this yourself or use a shared ID for participants to join the same call. |
| `userAuthToken` | The user auth token obtained from the CometChat REST API. |

## Start Call Session

Use the `startSession()` method to join a call session. This method requires a call token and a `CallSettings` object.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    guard let callToken = self.callToken else { return }

    let callSettings = CometChatCalls.CallSettingsBuilder
        .setDefaultLayout(true)
        .setIsAudioOnly(false)
        .setDelegate(self)
        .build()

    CometChatCalls.startSession(callToken: callToken, callSetting: callSettings, view: callView) { success in
        print("Call session started successfully")
    } onError: { error in
        print("Start session failed: \(String(describing: error?.errorDescription))")
    }
    ```
  </Tab>
</Tabs>

### Call Settings

Configure the call experience using the following `CallSettingsBuilder` methods:

| Method | Description |
| - | - |
| `setDefaultLayout(Bool)` | Enables or disables the default call UI layout with built-in controls. `true` shows the default layout. Default: `true` |
| `setIsAudioOnly(Bool)` | Sets whether the call is audio-only or audio-video. `true` for audio-only. Default: `false` |
| `setIsSingleMode(Bool)` | Enables single participant mode. |
| `setShowSwitchToVideoCall(Bool)` | Shows or hides the switch to video call button. |
| `setEnableVideoTileClick(Bool)` | Enables or disables click interactions on video tiles. Default: `true` |
| `setEnableDraggableVideoTile(Bool)` | Enables or disables drag functionality for video tiles in Spotlight mode. Default: `true` |
| `setEndCallButtonDisable(Bool)` | Shows or hides the end call button. Default: `false` (shown) |
| `setShowRecordingButton(Bool)` | Shows or hides the recording button. Default: `false` |
| `setSwitchCameraButtonDisable(Bool)` | Shows or hides the switch camera button. Default: `false` (shown) |
| `setMuteAudioButtonDisable(Bool)` | Shows or hides the mute audio button. Default: `false` (shown) |
| `setPauseVideoButtonDisable(Bool)` | Shows or hides the pause video button. Default: `false` (shown) |
| `setAudioModeButtonDisable(Bool)` | Shows or hides the audio mode selection button. Default: `false` (shown) |
| `setStartAudioMuted(Bool)` | Starts the call with the microphone muted. Default: `false` |
| `setStartVideoMuted(Bool)` | Starts the call with the camera turned off. Default: `false` |
| `setMode(DisplayModes)` | Sets the call UI layout mode. Available: `.default`, `.single`, `.spotlight`. Default: `.default` |
| `setAvatarMode(AvatarMode)` | Sets avatar display mode. Available: `.circle`, `.square`, `.fullscreen`. Default: `.circle` |
| `setDefaultAudioMode(AudioMode)` | Sets the initial audio output device. Available: `SPEAKER`, `EARPIECE`, `BLUETOOTH`, `HEADPHONES` |
| `setIdleTimeoutPeriod(Int)` | Sets idle timeout in seconds. Warning appears 60 seconds before auto-termination. Default: `180`. *v4.1.1+* |
| `setDelegate(self)` | Sets the delegate to receive call events. |

## Call Listeners

The `CallsEventsDelegate` protocol provides real-time callbacks for call session events.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    extension ViewController: CallsEventsDelegate {
        
        func onCallEnded() {
            // Call ended, close the calling screen
        }
        
        func onSessionTimeout() {
            // Session timed out due to inactivity
        }
        
        func onCallEndButtonPressed() {
            // User pressed end call button
            CometChatCalls.endSession()
            // Close the calling screen
        }
        
        func onUserJoined(rtcUser: RTCUser) {
            // A participant joined the call
        }
        
        func onUserLeft(rtcUser: RTCUser) {
            // A participant left the call
        }
        
        func onUserListChanged(rtcUsers: [RTCUser]) {
            // Participant list updated
        }
        
        func onAudioModeChanged(mode: [AudioMode]) {
            // Available audio devices changed
        }
        
        func onCallSwitchedToVideo(callSwitchedInfo: CallSwitchRequestInfo) {
            // Call upgraded from audio to video
        }
        
        func onUserMuted(rtcMutedUser: RTCMutedUser) {
            // A participant's mute state changed
        }
        
        func onRecordingToggled(recordingInfo: RTCRecordingInfo) {
            // Recording started or stopped
        }
    }
    ```
  </Tab>
</Tabs>

### Events

| Event | Description |
| - | - |
| `onCallEnded()` | Invoked when the call session terminates for a 1:1 call. Both participants receive this callback. |
| `onSessionTimeout()` | Invoked when the call is auto-terminated due to inactivity (default: 180 seconds). *v4.1.1+* |
| `onCallEndButtonPressed()` | Invoked when the local user taps the end call button. Call `CometChatCalls.endSession()` to leave the session. |
| `onUserJoined(rtcUser: RTCUser)` | Invoked when a remote participant joins. |
| `onUserLeft(rtcUser: RTCUser)` | Invoked when a remote participant leaves. |
| `onUserListChanged(rtcUsers: [RTCUser])` | Invoked whenever the participant list changes. |
| `onAudioModeChanged(mode: [AudioMode])` | Invoked when available audio devices change. |
| `onCallSwitchedToVideo(callSwitchedInfo: CallSwitchRequestInfo)` | Invoked when an audio call is upgraded to video. |
| `onUserMuted(rtcMutedUser: RTCMutedUser)` | Invoked when a participant's mute state changes. |
| `onRecordingToggled(recordingInfo: RTCRecordingInfo)` | Invoked when call recording starts or stops. |

## End Call Session

To end the call session and release all media resources, call `CometChatCalls.endSession()` in the `onCallEndButtonPressed()` callback.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    func onCallEndButtonPressed() {
        CometChatCalls.endSession()
        // Close the calling screen
    }
    ```
  </Tab>
</Tabs>

## Methods

These methods are available for performing custom actions during an active call session. Use them to build custom UI controls or implement specific behaviors based on your use case.

<Note>
  These methods can only be called when a call session is active.
</Note>

### Switch Camera

Toggles between the front and rear camera during a video call.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatCalls.switchCamera()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [CometChatCalls switchCamera];
    ```
  </Tab>
</Tabs>

### Mute Audio

Controls the local audio stream transmission.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    // Mute audio
    CometChatCalls.audioMuted(true)

    // Unmute audio
    CometChatCalls.audioMuted(false)
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    // Mute audio
    [CometChatCalls audioMuted:YES];

    // Unmute audio
    [CometChatCalls audioMuted:NO];
    ```
  </Tab>
</Tabs>

### Pause Video

Controls the local video stream transmission.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    // Pause video
    CometChatCalls.videoPaused(true)

    // Resume video
    CometChatCalls.videoPaused(false)
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    // Pause video
    [CometChatCalls videoPaused:YES];

    // Resume video
    [CometChatCalls videoPaused:NO];
    ```
  </Tab>
</Tabs>

### Set Audio Mode

Routes the audio output to a specific device.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatCalls.setAudioMode(AudioMode(mode: "SPEAKER"))
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [CometChatCalls setAudioModeWithMode:@"SPEAKER"];
    ```
  </Tab>
</Tabs>

### Enter PIP Mode

Enters Picture-in-Picture mode.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatCalls.enterPIPMode()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [CometChatCalls enterPIPMode];
    ```
  </Tab>
</Tabs>

### Exit PIP Mode

Exits Picture-in-Picture mode.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatCalls.exitPIPMode()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [CometChatCalls exitPIPMode];
    ```
  </Tab>
</Tabs>

### Switch To Video Call

Upgrades an ongoing audio call to a video call.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatCalls.switchToVideoCall()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [CometChatCalls switchToVideoCall];
    ```
  </Tab>
</Tabs>

### Start Recording

Starts recording the call session.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatCalls.startRecording()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [CometChatCalls startRecording];
    ```
  </Tab>
</Tabs>

### Stop Recording

Stops an ongoing call recording.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatCalls.stopRecording()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [CometChatCalls stopRecording];
    ```
  </Tab>
</Tabs>

### End Call

Terminates the current call session and releases all media resources.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    CometChatCalls.endSession()
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    [CometChatCalls endSession];
    ```
  </Tab>
</Tabs>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.