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

# Outgoing Call

> Display CometChat iOS UI Kit outgoing call screens with recipient details, cancel actions, custom sounds, and outgoing call callbacks.

The `CometChatOutgoingCall` component is a visual representation of a user-initiated call, whether voice or video. It serves as an interface for managing outgoing calls, providing users with essential options to control the call experience.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-rn-guide-message-privately/TO10Bmu50bb5qPTI/images/32f8b27c-out_going_call-4c017be781ae3fa02d30cb92ead32c25.png?fit=max&auto=format&n=TO10Bmu50bb5qPTI&q=85&s=16d4eec0a79d5e3933b1437950001d03" alt="CometChatOutgoingCall showing outgoing call interface with recipient avatar, name, and cancel button" width="1280" height="800" data-path="images/32f8b27c-out_going_call-4c017be781ae3fa02d30cb92ead32c25.png" />
</Frame>

<Accordion title="AI Integration Quick Reference">
  ```json theme={null}
  {
    "component": "CometChatOutgoingCall",
    "package": "CometChatUIKitSwift",
    "import": "import CometChatUIKitSwift\nimport CometChatSDK",
    "description": "Displays outgoing call interface while waiting for recipient to answer",
    "inherits": "UIViewController",
    "primaryOutput": {
      "callback": "onCancelClick",
      "type": "(Call, UIViewController) -> Void"
    },
    "props": {
      "data": {
        "call": { "type": "Call", "required": true }
      },
      "callbacks": {
        "onCancelClick": "(Call, UIViewController) -> Void",
        "onError": "(CometChatException) -> Void"
      },
      "sound": {
        "disableSoundForCalls": { "type": "Bool", "default": false },
        "customSoundForCalls": { "type": "URL?", "default": "nil" }
      },
      "viewSlots": {
        "listItemView": "(Call) -> UIView",
        "leadingView": "(Call) -> UIView",
        "titleView": "(Call) -> UIView"
      }
    },
    "events": [
      { "name": "onOutgoingCallAccepted", "payload": "Call", "description": "Fires when outgoing call is accepted" },
      { "name": "onOutgoingCallRejected", "payload": "Call", "description": "Fires when outgoing call is rejected" }
    ],
    "sdkListeners": [],
    "compositionExample": {
      "description": "OutgoingCall is presented when user initiates a call",
      "components": ["CometChatCallButtons", "CometChatOutgoingCall", "CometChatOngoingCall"],
      "flow": "User taps call → OutgoingCall shown → Recipient answers → OngoingCall starts"
    }
  }
  ```
</Accordion>

| Field     | Value                   |
| --------- | ----------------------- |
| Component | `CometChatOutgoingCall` |
| Package   | `CometChatUIKitSwift`   |
| Inherits  | `UIViewController`      |

***

## Usage

### Integration

`CometChatOutgoingCall` is a custom view controller that offers versatility in its integration. It can be seamlessly launched via button clicks or any user-triggered action, enhancing the overall user experience and facilitating smoother interactions within the application.

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    let cometChatOutgoingCall = CometChatOutgoingCall()
    cometChatOutgoingCall.set(call: call)

    cometChatOutgoingCall.modalPresentationStyle = .fullScreen
    self.present(cometChatOutgoingCall, animated: true)
    ```
  </Tab>
</Tabs>

<Note>
  If you are already using a navigation controller, you can use the `pushViewController` function instead of presenting the view controller.
</Note>

### Actions

[Actions](/ui-kit/ios/components-overview#actions) dictate how a component functions. They are divided into two types: Predefined and User-defined. You can override either type, allowing you to tailor the behavior of the component to fit your specific needs.

#### 1. SetOnCancelClick

The `setOnCancelClick` action is typically triggered when the call is canceled, carrying out default actions. You can customize or override this default behavior using the following code snippet:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    let cometChatOutgoingCall = CometChatOutgoingCall()
    cometChatOutgoingCall.set(onCancelClick: { call, controller in
        // Perform your action
    })
    ```
  </Tab>
</Tabs>

***

#### 2. OnError

You can customize error handling behavior by using the provided code snippet to override the `onError` callback:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    let incomingCallConfiguration = CometChatOutgoingCall()
    .set(onError: { error in
        // Perform your action
    })
    ```
  </Tab>
</Tabs>

***

### Filters

Filters allow you to customize the data displayed in a list within a Component. You can filter the list based on your specific criteria for a more customized experience. Filters can be applied using RequestBuilders of the Chat SDK.

The OutgoingCall component does not have any exposed filters.

***

### Events

[Events](/ui-kit/ios/components-overview#events) are emitted by a Component. By using events, you can extend existing functionality. Being global events, they can be applied in multiple locations and can be added or removed as needed.

| Event                      | Description                                  |
| -------------------------- | -------------------------------------------- |
| **onOutgoingCallAccepted** | Triggers when the outgoing call is accepted. |
| **onOutgoingCallRejected** | Triggers when the outgoing call is rejected. |

<Tabs>
  <Tab title="Add Listener">
    ```swift lines theme={null}
    // View controller from your project where you want to listen to events
    public class ViewController: UIViewController {

       public override func viewDidLoad() {
            super.viewDidLoad()

           // Subscribe to the listener for call events
            CometChatCallEvents.addListener("UNIQUE_ID", self as CometChatCallEventListener)
        }
    }

    // Listener for call events
    extension ViewController: CometChatCallEventListener {

        func onOutgoingCallAccepted(call: Call) {
            // Handle call accepted
        }

        func onOutgoingCallRejected(call: Call) {
            // Handle call rejected
        }
    }
    ```

    ```swift Emitting Call Events theme={null}
    // Emit this when the other user accepts the call
    CometChatCallEvents.emitOnOutgoingCallAccepted(call: Call)

    // Emit this when the other user rejects a call
    CometChatCallEvents.emitOnOutgoingCallRejected(call: Call)
    ```
  </Tab>
</Tabs>

<Tabs>
  <Tab title="Remove Listener">
    ```swift lines theme={null}
    public override func viewWillDisappear(_ animated: Bool) {
          // Unsubscribe from the listener
          CometChatCallEvents.removeListener("LISTENER_ID_USED_FOR_ADDING_THIS_LISTENER")
    }
    ```
  </Tab>
</Tabs>

***

## Customization

To fit your app's design requirements, you can customize the appearance of the component. We provide exposed methods that allow you to modify the experience and behavior according to your specific needs.

### Style

Using Style, you can customize the look and feel of the component in your app. These parameters typically control elements such as the color, size, shape, and fonts used within the component.

#### 1. OutgoingCall Style

You can customize the appearance of the `OutgoingCall` Component by applying the `OutgoingCallStyle` to it.

**Global level styling**

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    let customAvatarStyle = AvatarStyle()
    customAvatarStyle.backgroundColor = UIColor(hex: "#FBAA75")
    customAvatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8)
            
    CometChatOutgoingCall.style.nameLabelFont = UIFont(name: "Times-New-Roman", size: 20)
    CometChatOutgoingCall.style.callLabelFont = UIFont(name: "Times-New-Roman", size: 14)
    CometChatOutgoingCall.style.declineButtonCornerRadius = .init(cornerRadius: 8)
    CometChatOutgoingCall.avatarStyle = customAvatarStyle
    ```
  </Tab>
</Tabs>

**Instance level styling**

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    let customAvatarStyle = AvatarStyle()
    customAvatarStyle.backgroundColor = UIColor(hex: "#FBAA75")
    customAvatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8)
            
    let outgoingCallStyle = OutgoingCallStyle()
    outgoingCallStyle.nameLabelFont = UIFont(name: "Times-New-Roman", size: 20)
    outgoingCallStyle.callLabelFont = UIFont(name: "Times-New-Roman", size: 14)
    outgoingCallStyle.declineButtonCornerRadius = .init(cornerRadius: 8)
            
    let outgoingCall = CometChatOutgoingCall()
    outgoingCall.style = outgoingCallStyle
    outgoingCall.avatarStyle = customAvatarStyle
    ```
  </Tab>
</Tabs>

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-rn-guide-message-privately/mNTojjz_O28of40c/images/f63774e9-outgoing_call_style-f711bde22eb1d17f80f5f52e59e5a8ed.png?fit=max&auto=format&n=mNTojjz_O28of40c&q=85&s=212087864837c38c06a03c2a48afbeab" alt="CometChatOutgoingCall with custom styling showing custom fonts and rounded decline button" width="1280" height="800" data-path="images/f63774e9-outgoing_call_style-f711bde22eb1d17f80f5f52e59e5a8ed.png" />
</Frame>

#### OutgoingCallStyle Properties

| Property                       | Description                                                                 | Code                                                                                     |
| ------------------------------ | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `backgroundColor`              | Sets the background color for the outgoing call view.                       | `CometChatOutgoingCall.style.backgroundColor = UIColor()`                                |
| `borderColor`                  | Sets the border color for the outgoing call view.                           | `CometChatOutgoingCall.style.borderColor = UIColor.clear`                                |
| `borderWidth`                  | Sets the border width for the outgoing call view.                           | `CometChatOutgoingCall.style.borderWidth = 0`                                            |
| `cornerRadius`                 | Sets the corner radius for the outgoing call view.                          | `CometChatOutgoingCall.style.cornerRadius = .init(cornerRadius: 0)`                      |
| `nameTextColor`                | Sets the text color for the name label in the outgoing call view.           | `CometChatOutgoingCall.style.nameTextColor = UIColor()`                                  |
| `nameTextFont`                 | Sets the font for the name label in the outgoing call view.                 | `CometChatOutgoingCall.style.nameTextFont = UIFont()`                                    |
| `callTextColor`                | Sets the text color for the call label in the outgoing call view.           | `CometChatOutgoingCall.style.callTextColor = UIColor()`                                  |
| `callTextFont`                 | Sets the font for the call label in the outgoing call view.                 | `CometChatOutgoingCall.style.callTextFont = UIFont()`                                    |
| `declineButtonBackgroundColor` | Sets the background color for the decline button in the outgoing call view. | `CometChatOutgoingCall.style.declineButtonBackgroundColor = UIColor()`                   |
| `declineButtonIconTint`        | Sets the tint color for the decline button icon.                            | `CometChatOutgoingCall.style.declineButtonIconTint = UIColor()`                          |
| `declineButtonIcon`            | Sets the icon for the decline button.                                       | `CometChatOutgoingCall.style.declineButtonIcon = UIImage(systemName: "phone.down.fill")` |
| `declineButtonCornerRadius`    | Sets the corner radius for the decline button.                              | `CometChatOutgoingCall.style.declineButtonCornerRadius: CometChatCornerStyle?`           |
| `declineButtonBorderColor`     | Sets the border color for the decline button.                               | `CometChatOutgoingCall.style.declineButtonBorderColor: UIColor?`                         |
| `declineButtonBorderWidth`     | Sets the border width for the decline button.                               | `CometChatOutgoingCall.style.declineButtonBorderWidth: CGFloat?`                         |

***

### Functionality

These are small functional customizations that allow you to fine-tune the overall experience of the component.

| Property               | Description                             | Code                            |
| ---------------------- | --------------------------------------- | ------------------------------- |
| disableSoundForCalls   | Disables sound for outgoing calls.      | `disableSoundForCalls = true`   |
| setCustomSoundForCalls | Sets a custom sound for outgoing calls. | `set(customSoundForCalls: URL)` |

### Advanced

For advanced-level customization, you can set custom views to the component. This lets you tailor each aspect of the component to fit your exact needs and application aesthetics. You can create and define your own views, layouts, and UI elements and then incorporate those into the component.

#### SetAvatarView

With this function, you can assign a custom view to the avatar of the OutgoingCall Component.

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    cometChatOutgoingCall.set(avatarView: { call in
        let customView = CustomAvatarView()
        return customView
    })
    ```
  </Tab>
</Tabs>

**Demonstration**

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-rn-guide-message-privately/2JiXkJ8lq6PmPGlJ/images/6e8d50eb-outgoingAvatar-a60e0c08776349bdab9a51a114b241aa.png?fit=max&auto=format&n=2JiXkJ8lq6PmPGlJ&q=85&s=b75d63a283934376c70a33c19c258141" alt="CometChatOutgoingCall with custom avatar view showing profile image with star badge overlay" width="1280" height="800" data-path="images/6e8d50eb-outgoingAvatar-a60e0c08776349bdab9a51a114b241aa.png" />
</Frame>

You can create a `CustomAvatarView` as a custom `UIView`:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    import UIKit

    class CustomAvatarView: UIView {
        
        private let imageView: UIImageView = {
            let imageView = UIImageView(image: UIImage(named: "user_profile")) // Replace with actual image
            imageView.contentMode = .scaleAspectFill
            imageView.layer.cornerRadius = 50
            imageView.layer.masksToBounds = true
            imageView.translatesAutoresizingMaskIntoConstraints = false
            return imageView
        }()
        
        private let badgeView: UIView = {
            let view = UIView()
            view.backgroundColor = .yellow
            view.layer.cornerRadius = 14
            view.translatesAutoresizingMaskIntoConstraints = false
            return view
        }()
        
        private let starIcon: UIImageView = {
            let imageView = UIImageView(image: UIImage(systemName: "star.fill"))
            imageView.tintColor = .white
            imageView.translatesAutoresizingMaskIntoConstraints = false
            return imageView
        }()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            setupView()
        }
        
        private func setupView() {
            translatesAutoresizingMaskIntoConstraints = false
            
            addSubview(imageView)
            addSubview(badgeView)
            badgeView.addSubview(starIcon)
            
            NSLayoutConstraint.activate([
                imageView.centerXAnchor.constraint(equalTo: centerXAnchor),
                imageView.centerYAnchor.constraint(equalTo: centerYAnchor),
                imageView.widthAnchor.constraint(equalToConstant: 100),
                imageView.heightAnchor.constraint(equalToConstant: 100),
                
                badgeView.trailingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 5),
                badgeView.bottomAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 5),
                badgeView.widthAnchor.constraint(equalToConstant: 28),
                badgeView.heightAnchor.constraint(equalToConstant: 28),
                
                starIcon.centerXAnchor.constraint(equalTo: badgeView.centerXAnchor),
                starIcon.centerYAnchor.constraint(equalTo: badgeView.centerYAnchor),
                starIcon.widthAnchor.constraint(equalToConstant: 14),
                starIcon.heightAnchor.constraint(equalToConstant: 14)
            ])
        }
    }
    ```
  </Tab>
</Tabs>

***

#### SetCancelView

You can modify the cancel call view of the Outgoing call component using the property below:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    cometChatOutgoingCall.set(cancelView: { call in
        let view = CustomCancelView()
        return view
    })
    ```
  </Tab>
</Tabs>

**Demonstration**

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-rn-guide-message-privately/FGBCGWXGo5d9bVxR/images/c4dbb8db-outgoingCancel-f77fb4543389066b3209647d155a2f91.png?fit=max&auto=format&n=FGBCGWXGo5d9bVxR&q=85&s=8bc78a5c1eb84e384e5bfb3760671f01" alt="CometChatOutgoingCall with custom cancel view showing red End Call button with phone icon" width="1280" height="800" data-path="images/c4dbb8db-outgoingCancel-f77fb4543389066b3209647d155a2f91.png" />
</Frame>

You can create a `CustomCancelView` as a custom `UIView`:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    import UIKit

    class EndCallButton: UIButton {
        
        private let phoneIcon: UIImageView = {
            let imageView = UIImageView(image: UIImage(systemName: "phone.down.fill"))
            imageView.tintColor = .white
            imageView.translatesAutoresizingMaskIntoConstraints = false
            return imageView
        }()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            setupView()
        }
        
        private func setupView() {
            setTitle("End Call", for: .normal)
            setTitleColor(.white, for: .normal)
            backgroundColor = .red
            layer.cornerRadius = 10
            titleLabel?.font = UIFont.systemFont(ofSize: 18)
            translatesAutoresizingMaskIntoConstraints = false
            
            let stackView = UIStackView(arrangedSubviews: [phoneIcon, titleLabel!])
            stackView.axis = .horizontal
            stackView.spacing = 5
            stackView.alignment = .center
            stackView.translatesAutoresizingMaskIntoConstraints = false
            
            addSubview(stackView)
            
            NSLayoutConstraint.activate([
                stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
                stackView.centerYAnchor.constraint(equalTo: centerYAnchor)
            ])
            
            addTarget(self, action: #selector(endCallTapped), for: .touchUpInside)
        }
        
        @objc private func endCallTapped() {
            print("Call Ended")
        }
    }
    ```
  </Tab>
</Tabs>

***

#### SetTitleView

You can customize the title view of the outgoing call component using the property below:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    cometChatOutgoingCall.set(titleView: { call in
        let view = CustomTitleView()
        view.configure(call: call)
        return view
    })
    ```
  </Tab>
</Tabs>

**Demonstration**

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-rn-guide-message-privately/G6Puyz_3Zlaowa9R/images/cac65645-outgoingTitle-00c457abaa1c05fa3b7e85bfb013b5a7.png?fit=max&auto=format&n=G6Puyz_3Zlaowa9R&q=85&s=b1110c48d88cb90acb48add7f0dee3d6" alt="CometChatOutgoingCall with custom title view showing call initiator and receiver names" width="1280" height="800" data-path="images/cac65645-outgoingTitle-00c457abaa1c05fa3b7e85bfb013b5a7.png" />
</Frame>

You can create a `CustomTitleView` as a custom `UIView`:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    import UIKit

    class CustomTitleView: UILabel {
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            setupView()
        }
        
        private func setupView() {
            font = UIFont.boldSystemFont(ofSize: 22)
            textAlignment = .center
            translatesAutoresizingMaskIntoConstraints = false
        }

        func configure(call: Call) {
            text = "\(call.callInitiator) <> \(call.receiver)"
        }
    }
    ```
  </Tab>
</Tabs>

***

#### SetSubtitleView

You can modify the subtitle view of the outgoing call component using the property below:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    cometChatOutgoingCall.set(subtitleView: { call in
        let view = CustomSubtitleView()
        return view
    })
    ```
  </Tab>
</Tabs>

**Demonstration**

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-rn-guide-message-privately/ugckbRl5Q-H7t8X2/images/e207e59d-outgoingSubtitle-d5d031d766f72d34cee90230b1a5ab86.png?fit=max&auto=format&n=ugckbRl5Q-H7t8X2&q=85&s=fcb8ca96d9f7af2475a19325b002abbd" alt="CometChatOutgoingCall with custom subtitle view showing phone icon and Calling status text" width="1280" height="800" data-path="images/e207e59d-outgoingSubtitle-d5d031d766f72d34cee90230b1a5ab86.png" />
</Frame>

You can create a `CustomSubtitleView` as a custom `UIView`:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    import UIKit

    class CustomSubtitleView: UIStackView {
        
        private let phoneIcon: UIImageView = {
            let imageView = UIImageView(image: UIImage(systemName: "phone.fill"))
            imageView.tintColor = .gray
            imageView.translatesAutoresizingMaskIntoConstraints = false
            return imageView
        }()
        
        private let callingLabel: UILabel = {
            let label = UILabel()
            label.text = "Calling..."
            label.textColor = .gray
            label.font = UIFont.systemFont(ofSize: 18)
            label.translatesAutoresizingMaskIntoConstraints = false
            return label
        }()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupView()
        }
        
        required init(coder: NSCoder) {
            super.init(coder: coder)
            setupView()
        }
        
        private func setupView() {
            axis = .horizontal
            spacing = 5
            alignment = .center
            translatesAutoresizingMaskIntoConstraints = false
            
            addArrangedSubview(phoneIcon)
            addArrangedSubview(callingLabel)
        }
    }
    ```
  </Tab>
</Tabs>

***

## Props

All props are optional unless noted.

***

### call

The outgoing call object to display.

|         |             |
| ------- | ----------- |
| Type    | `Call`      |
| Default | `undefined` |

***

### disableSoundForCalls

Disables the outgoing call ringtone.

|         |         |
| ------- | ------- |
| Type    | `Bool`  |
| Default | `false` |

***

### customSoundForCalls

Custom sound file URL for outgoing calls.

|         |        |
| ------- | ------ |
| Type    | `URL?` |
| Default | `nil`  |

***

### avatarStyle

Customizes the appearance of the recipient's avatar.

|         |                 |
| ------- | --------------- |
| Type    | `AvatarStyle`   |
| Default | `AvatarStyle()` |

```swift lines theme={null}
import CometChatUIKitSwift

let customAvatarStyle = AvatarStyle()
customAvatarStyle.backgroundColor = UIColor.systemOrange
customAvatarStyle.cornerRadius = CometChatCornerStyle(cornerRadius: 8)

let outgoingCall = CometChatOutgoingCall()
outgoingCall.avatarStyle = customAvatarStyle
```

***

## Events

Events emitted by the Outgoing Call component:

| Event                    | Description                                                  |
| ------------------------ | ------------------------------------------------------------ |
| `onOutgoingCallAccepted` | Triggers when the outgoing call is accepted by the recipient |
| `onOutgoingCallRejected` | Triggers when the outgoing call is rejected by the recipient |

***

## View Slots

| Slot           | Signature          | Replaces           |
| -------------- | ------------------ | ------------------ |
| `avatarView`   | `(Call) -> UIView` | Recipient avatar   |
| `cancelView`   | `(Call) -> UIView` | Cancel call button |
| `titleView`    | `(Call) -> UIView` | Recipient name     |
| `subtitleView` | `(Call) -> UIView` | "Calling..." text  |
| `leadingView`  | `(Call) -> UIView` | Left section       |
| `trailingView` | `(Call) -> UIView` | Right section      |

### leadingView

You can customize the leading view of an outgoing call component using the property below.

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    cometChatOutgoingCall.set(leadingView: { call in
        let view = CustomLeadingView()
        return view
    })
    ```
  </Tab>
</Tabs>

### trailingView

You can customize the trailing view of an outgoing call component using the property below.

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    cometChatOutgoingCall.set(trailingView: { call in
        let view = CustomTrailingView()
        return view
    })
    ```
  </Tab>
</Tabs>

***

## Common Patterns

### Initiate Call and Present Outgoing Screen

Start a call and show the outgoing call interface:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    func initiateCall(to user: User, callType: CometChat.CallType) {
        let call = Call(receiverId: user.uid ?? "", callType: callType, receiverType: .user)
        
        CometChat.initiateCall(call: call) { [weak self] initiatedCall in
            guard let initiatedCall = initiatedCall else { return }
            DispatchQueue.main.async {
                let outgoingCall = CometChatOutgoingCall()
                outgoingCall.set(call: initiatedCall)
                outgoingCall.modalPresentationStyle = .fullScreen
                self?.present(outgoingCall, animated: true)
            }
        } onError: { error in
            print("Call initiation failed: \(error?.errorDescription ?? "")")
        }
    }
    ```
  </Tab>
</Tabs>

### Handle Call Acceptance and Transition to Ongoing Call

Navigate to ongoing call when the recipient accepts:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    // Subscribe to call events
    CometChatCallEvents.addListener("outgoing_call_listener", self as CometChatCallEventListener)

    // In CometChatCallEventListener extension
    func onOutgoingCallAccepted(call: Call) {
        DispatchQueue.main.async { [weak self] in
            self?.dismiss(animated: false) {
                let ongoingCall = CometChatOngoingCall()
                ongoingCall.set(sessionId: call.sessionId ?? "")
                ongoingCall.modalPresentationStyle = .fullScreen
                self?.present(ongoingCall, animated: true)
            }
        }
    }
    ```
  </Tab>
</Tabs>

### Custom Cancel Action with Confirmation

Show confirmation before canceling an outgoing call:

<Tabs>
  <Tab title="Swift">
    ```swift lines theme={null}
    let outgoingCall = CometChatOutgoingCall()
    outgoingCall.set(call: call)
    outgoingCall.set(onCancelClick: { [weak self] call, controller in
        let alert = UIAlertController(
            title: "Cancel Call",
            message: "Are you sure you want to cancel this call?",
            preferredStyle: .alert
        )
        alert.addAction(UIAlertAction(title: "No", style: .cancel))
        alert.addAction(UIAlertAction(title: "Yes", style: .destructive) { _ in
            CometChat.rejectCall(sessionID: call.sessionId ?? "", status: .cancelled) { _ in
                controller.dismiss(animated: true)
            } onError: { error in
                print("Failed to cancel: \(error?.errorDescription ?? "")")
            }
        })
        controller.present(alert, animated: true)
    })
    ```
  </Tab>
</Tabs>

***

## Related Components

<CardGroup cols={3}>
  <Card title="Incoming Call" href="/ui-kit/ios/incoming-call">
    Display incoming call interface
  </Card>

  <Card title="Ongoing Call" href="/ui-kit/ios/ongoing-call">
    Display active call interface
  </Card>

  <Card title="Call Logs" href="/ui-kit/ios/call-logs">
    Display call history
  </Card>
</CardGroup>
