TVOCall

Objective-C

@interface TVOCall : NSObject

Swift

class TVOCall : NSObject

The TVOCall class represents a signaling and media session between the host device and Twilio infrastructure. Calls can represent an outbound call initiated from the SDK via <[TwilioVoiceSDK connectWithAccessToken:delegate:]> or an incoming call accepted via a <[TVOCallInvite acceptWithDelegate:]>. Devices that initiate an outbound call represent the caller and devices that receive a <TVOCallInvite> represent the callee.

The lifecycle of a call differs for the caller and the callee. Making or accepting a call requires a <TVOCallDelegate> which receives call state changes defined in <TVOCallState>. The <TVOCallState> can be obtained at any time from the state property of TVOCall.

The caller callback behavior is affected by the answerOnBridge flag provided in the Dial verb of your TwiML application associated with this client. If the answerOnBridge flag is false, which is the default, the <[TVOCallDelegate callDidConnect:]> callback will be emitted immediately after <[TVOCallDelegate callDidStartRinging:]>. If the answerOnBridge flag is true this will cause the call to emit the <[TVOCallDelegate callDidConnect:]> callback only until the call is answered. See Answer on Bridge documentation for more details on how to use it with the Dial TwiML verb.

The following table provides expected call sequences for common scenarios from the perspective of the caller:

Scenario`` Callbacks`` Transitions
A call is initiated and the caller disconnects before reaching the ringing state.
  1. `<[TVOCallDelegate call:didDisconnectWithError:]>`
  1. `TVOCallStateConnecting`
  2. `TVOCallStateDisconnected`
A call is initiated, reaches the ringing state and the caller disconnects before being connected.
  1. `<[TVOCallDelegate callDidStartRinging:]>`
  2. `<[TVOCallDelegate call:didDisconnectWithError:]>`
  1. `TVOCallStateConnecting`
  2. `TVOCallStateRinging`
  3. `TVOCallStateDisconnected`
A call is initiated and the call fails to connect before reaching the ringing state.
  1. `<[TVOCallDelegate call:didFailToConnectWithError:]>`
  1. `TVOCallStateConnecting`
  2. `TVOCallStateDisconnected`
A call is initiated and the call fails to connect after reaching the ringing state.
  1. `<[TVOCallDelegate callDidStartRinging:]>`
  2. `<[TVOCallDelegate call:didFailToConnectWithError:]>`
  1. `TVOCallStateConnecting`
  2. `TVOCallStateRinging`
  3. `TVOCallStateDisconnected`
A call is initiated, becomes connected, and ends for one of the following reasons:
  • The caller disconnects the call
  • The callee disconnects the call
  • An on-device error occurs. (eg. network loss)
  • An error between the caller and callee occurs. (eg. media connection lost or Twilio infrastructure failure)
  1. `<[TVOCallDelegate callDidStartRinging:]>`
  2. `<[TVOCallDelegate callDidConnect:]>`
  3. `<[TVOCallDelegate call:didDisconnectWithError:]>`
  1. `TVOCallStateConnecting`
  2. `TVOCallStateRinging`
  3. `TVOCallStateConnected`
  4. `TVOCallStateDisconnected`

The following table provides expected call sequences for common scenarios from the callee perspective:

Scenario`` Callbacks`` Transitions
A `` is accepted and the callee disconnects the call before being connected.
  1. `<[TVOCallDelegate call:didDisconnectWithError:]>`
  1. `TVOCallStateConnecting`
  2. `TVOCallStateDisconnected`
A `` is accepted and the call fails to connect.
  1. `<[TVOCallDelegate call:didFailToConnectWithError:]>`
  1. `TVOCallStateConnecting`
  2. `TVOCallStateDisconnected`
A `` is accepted, becomes connected, and ends for one of the following reasons:
  • The caller disconnects the call
  • The callee disconnects the call
  • An on-device error occurs. (eg. network loss)
  • An error between the caller and callee occurs. (eg. media connection lost or Twilio infrastructure failure)
  1. `<[TVOCallDelegate callDidStartRinging:]>`
  2. `<[TVOCallDelegate callDidConnect:]>`
  3. `<[TVOCallDelegate call:didDisconnectWithError:]>`
  1. `TVOCallStateConnecting`
  2. `TVOCallStateRinging`
  3. `TVOCallStateConnected`
  4. `TVOCallStateDisconnected`

It is important to call the <[TVOCall disconnect]> method to terminate the call. Not calling <[TVOCall disconnect]> results in leaked native resources and may lead to an out-of-memory crash. If the call is disconnected by the caller, callee, or Twilio, the SDK will automatically free native resources. However, <[TVOCall disconnect]> is an idempotent operation so it is best to call this method when you are certain your application no longer needs the object.

It is strongly recommended that <TVOCall> instances are created and accessed from a single dispatch queue. Accessing a <TVOCall> instance from multiple queues may cause synchronization problems. <TVOCallDelegate> methods are called on the main dispatch queue by default or on the delegateQueue provided to <TVOConnectOptions> or <TVOAcceptOptions> upon initiating or accepting a call.

An ongoing call will automatically switch to a more preferred network type if one becomes available. The following are the network types listed in preferred order: ETHERNET, LOOPBACK, WIFI, VPN, and CELLULAR. For example, if a WIFI network becomes available whilst in a call that is using CELLULAR data, the call will automatically switch to using the WIFI network.

Media and signaling reconnections are handled independently. As a result, it is possible that a single network change event produces consecutive [TVOCallDelegate call:isReconnectingWithError:] and [TVOCallDelegate callDidReconnect:] callbacks. For example, a network change may result in the following callback sequence.

  • [TVOCallDelegate call:isReconnectingWithError:] with error.code TVOErrorSignalingConnectionDisconnectedError.
  • [TVOCallDelegate callDidReconnect:].
  • [TVOCallDelegate call:isReconnectingWithError:] with error.code TVOErrorMediaConnectionError.
  • [TVOCallDelegate callDidReconnect:].

Note that the SDK will always raise a [TVOCallDelegate call:isReconnectingWithError:] callback followed by a [TVOCallDelegate callDidReconnect:] callback when reconnection is successful.

During the reconnecting state operations such as [TVOCall setOnHold:], [TVOCall setMuted:], [TVOCall sendDigits:] will result in undefined behavior. When building applications, the recommended practice is to show a UI update when the Call enters reconnecting regardless of the cause, and then clear the UI update once the call has reconnected or disconnected.

Insights

The following connection events are reported to Insights during a call:

Group NameEvent NameDescriptionSince version
connectionmutedAudio input of the call is muted by calling `<[TVOCall setMuted:]>` with `YES`.3.0.0-beta2
connectionunmutedAudio input of the call is unmuted by calling `<[TVOCall setMuted:]>` with `NO`.3.0.0-beta2
connectionaccepted-by-remoteServer returns an answer to the Client’s offer over the signaling channel.3.0.0-beta2
connectionringingCall state transitions to `TVOCallStateRinging`.3.0.0-beta2
connectionconnectedCall state transitions to `TVOCallStateConnected`.3.0.0-beta2
connectiondisconnect-called`<[TVOCall disconnect]>` is called.3.0.0-beta2
connectiondisconnected-by-localCall disconnected as a result of calling `<[TVOCall disconnect]>`. Call transitions to `TVOCallStateDisconnected`.3.0.0-beta2
connectiondisconnected-by-remoteCall is disconnected by the remote. Call transitions to `TVOCallStateDisconnected`.3.0.0-beta2
connectionholdCall is on hold by calling `<[TVOCall setOnHold:]>` with `YES`.3.0.0-beta2
connectionunholdCall is on unhold by calling `<[TVOCall setOnHold:]>` with `NO`.3.0.0-beta2
connectionerrorError description. Call state transitions to `TVOCallStateDisconnected`.3.0.0-beta2
connectionreconnectingThe Call is attempting to recover from a signaling or media connection interruption3.0.0-beta3
connectionreconnectedThe Call has recovered from a signaling or media connection interruption3.0.0-beta3

The following peer connection state events are reported to Insights during a call:

Group NameEvent NameDescriptionSince version
pc-connection-statenewThe PeerConnection ice connection state changed to “new”.6.0.0
pc-connection-stateconnectingThe PeerConnection state changed to “connecting”.6.0.0
pc-connection-stateconnectedThe PeerConnection state changed to “connected”.6.0.0
pc-connection-statedisconnectedThe PeerConnection state changed to “disconnected”.6.0.0
pc-connection-statefailedThe PeerConnection state changed to “failed”.6.0.0
pc-connection-stateclosedThe PeerConnection state changed to “closed”.6.0.0

The following ICE candidate event is reported to Insights during a call:

Group NameEvent NameDescriptionSince version
ice-candidateice-candidateICE candidate events are raised when `OnIceCandidate` is called on the `PeerConnection`4.1.0
ice-candidateselected-ice-candidate-pairThe active local ICE candidate and remote ICE candidate6.0.0

The following ICE connection state events are reported to Insights during a call:

Group NameEvent NameDescriptionSince version
ice-connection-statenewThe PeerConnection ice connection state changed to “new”.3.0.0-beta3
ice-connection-statecheckingThe PeerConnection ice connection state changed to “checking”.3.0.0-beta3
ice-connection-stateconnectedThe PeerConnection ice connection state changed to “connected”.3.0.0-beta3
ice-connection-statecompletedThe PeerConnection ice connection state changed to “completed”.3.0.0-beta3
ice-connection-stateclosedThe PeerConnection ice connection state changed to “closed”.3.0.0-beta3
ice-connection-statedisconnectedThe PeerConnection ice connection state changed to “disconnected”.3.0.0-beta3
ice-connection-statefailedThe PeerConnection ice connection state changed to “failed”.3.0.0-beta3

The following ICE gathering state events are reported to Insights during a call:

Group NameEvent NameDescriptionSince version
ice-gathering-statenewThe PeerConnection ice gathering state changed to “new”.3.0.0-beta3
ice-gathering-stategatheringThe PeerConnection ice gathering state changed to “checking”.3.0.0-beta3
ice-gathering-statecompleteThe PeerConnection ice gathering state changed to “connected”.3.0.0-beta3

The following signaling state events are reported to Insights during a call:

Group NameEvent NameDescriptionSince version
signaling-statestableThe PeerConnection signaling state changed to “stable”.3.0.0-beta3
signaling-statehave-local-offerThe PeerConnection signaling state changed to “have-local-offer”.3.0.0-beta3
signaling-statehave-remote-offersThe PeerConnection signaling state changed to “have-remote-offers”.3.0.0-beta3
signaling-statehave-local-pranswerThe PeerConnection signaling state changed to “have-local-pranswer”.3.0.0-beta3
signaling-statehave-remote-pranswerThe PeerConnection signaling state changed to “have-remote-pranswer”.3.0.0-beta3
signaling-stateclosedThe PeerConnection signaling state changed to “closed”.3.0.0-beta3

The following network quality warning and network quality warning cleared events are reported to Insights during a call:

Group NameEvent NameDescriptionSince version
network-quality-warning-raisedhigh-jitterThree out of last five jitter samples exceed 30 ms.3.0.0-beta3
network-quality-warning-clearedhigh-jitterhigh-jitter warning cleared if last five jitter samples are less than 30 ms.3.0.0-beta3
network-quality-warning-raisedlow-mosThree out of last five mos samples are lower than 3.5.3.0.0-beta3
network-quality-warning-clearedlow-moslow-mos cleared if last five mos samples are higher than 3.5.3.0.0-beta3
network-quality-warning-raisedhigh-packets-lost-fractionThe average packet loss > 3% in last 7 samples.3.0.0-beta3
network-quality-warning-clearedhigh-packets-lost-fractionhigh-packets-lost-fraction cleared if average packet loss <= 1% in last 7 samples.3.0.0-beta3
network-quality-warning-raisedhigh-rttThree out of last five RTT samples show greater than 400 ms.3.0.0-beta3
network-quality-warning-clearedhigh-rtthigh-rtt warning cleared if last five RTT samples are lower than 400 ms.3.0.0-beta3

The following audio level warning and audio level warning cleared events are reported to Insights during a call

Group NameEvent NameDescriptionSince version
audio-level-warning-raisedconstant-audio-input-levelThe standard deviation of audio input levels for last 10 samples is less than or equals 1% of the maximum possible audio input level (32767) i.e. 327.67 and the call is not in the muted state3.0.0-beta3
audio-level-warning-clearedconstant-audio-input-levelconstant-audio-input-level warning cleared if the standard deviation of audio input levels for last 10 samples is greater than 3% of the maximum possible audio input level.3.0.0-beta3
audio-level-warning-raisedconstant-audio-output-levelThe standard deviation of audio output levels for last 10 samples is less than or equals 1% of the maximum possible audio output level (32767) i.e. 327.67 and the local call is not placed on hold6.11.0
audio-level-warning-clearedconstant-audio-output-levelconstant-audio-output-level warning cleared if the standard deviation of audio output levels for last 10 samples is greater than 3% of the maximum possible audio output level.6.11.0

The following feedback events are reported to Insights during a call:

Group NameEvent NameDescriptionSince version
feedbackreceived`<[TVOCall postFeedback:issue:]>` is called if the score is not `TVOCallFeedbackScoreNotReported` or the issue type is not `TVOCallFeedbackIssueNotReported`.3.0.0-beta3
feedbackreceived-none`<[TVOCall postFeedback:issue:]>` is called if the score is `TVOCallFeedbackScoreNotReported` and the issue type is `TVOCallFeedbackIssueNotReported`.3.0.0-beta3

Properties

  • @brief From value of the Call.

    @discussion This may be nil if the call object was created by calling the <[TwilioVoiceSDK connectWithOptions:delegate:]> method or if the call object was created by calling the <[TVOCallInvite acceptWithOptions:delegate:]> method where the from value of the TVOCallInvite object was also nil.

    Declaration

    Objective-C

    @property (nonatomic, strong, readonly, nullable) NSString *from;

    Swift

    var from: String? { get }
  • to

    @brief To value of the Call.

    @discussion This may be nil if the call object was created by calling the <[TwilioVoiceSDK connectWithOptions:delegate:]> method.

    Declaration

    Objective-C

    @property (nonatomic, strong, readonly, nullable) NSString *to;

    Swift

    var to: String? { get }
  • sid

    @brief A server assigned identifier (SID) for the Call.

    @discussion A SID is a globally unique identifier which can be very useful for debugging Call traffic. The Call sid may be nil until the call is in TVOCallStateRinging state.

    Declaration

    Objective-C

    @property (nonatomic, strong, readonly, nonnull) NSString *sid;

    Swift

    var sid: String { get }
  • @brief Property that defines if the Call is muted.

    @discussion The Voice SDK’s media engine will start sending silent audio frames when the Call is muted. Setting the property will only take effect if the <state> is TVOCallStateConnected.

    Declaration

    Objective-C

    @property (nonatomic, getter=isMuted) BOOL muted;

    Swift

    var isMuted: Bool { get set }
  • @brief The current state of the Call.

    @discussion All TVOCall instances start in TVOCallStateConnecting and end in TVOCallStateDisconnected. After creation, a Call will transition to TVOCallStateConnected if successful or TVOCallStateDisconnected if the connection attempt fails.

    See

    TVOCallState

    Declaration

    Objective-C

    @property (nonatomic, readonly) TVOCallState state;

    Swift

    var state: TVOCallState { get }
  • @brief Property that defines if the Call is on hold.

    @discussion If the Call is on hold, The Voice SDK’s media engine will send silent audio frames to the remote party, and remote party’s audio playback will be disabled.

    Declaration

    Objective-C

    @property (nonatomic, getter=isOnHold) BOOL onHold;

    Swift

    var isOnHold: Bool { get set }
  • @brief The current set of Call quality warnings.

    @discussion Values in the <NSSet> are <NSNumber> with values of <TVOCallQualityWarning>.

    Declaration

    Objective-C

    @property (nonatomic, strong, readonly, nonnull) NSSet *callQualityWarnings;

    Swift

    var callQualityWarnings: Set<AnyHashable> { get }

General Call Actions

  • @brief Disconnects the Call.

    @discussion Calling this method on a TVOCall that is in the <state> TVOCallStateDisconnected has no effect.

    Declaration

    Objective-C

    - (void)disconnect;

    Swift

    func disconnect()
  • @brief Send a string of digits.

    @discussion Calling this method on a TVOCall that is not in the <state> TVOCallStateConnected has no effect.

    Declaration

    Objective-C

    - (void)sendDigits:(nonnull NSString *)digits;

    Swift

    func sendDigits(_ digits: String)

    Parameters

    digits

    A string of characters to be played. Valid values are ‘0’ - ‘9’, ‘*’, ‘#’, and ‘w’. Each ‘w’ will cause a 500 ms pause between digits sent.

  • @brief Retrieve stats for the audio track.

    @discussion The call needs to be in the <state> TVOCallStateConnected for stats reports to be delivered.

    Declaration

    Objective-C

    - (void)getStatsWithBlock:(nonnull TVOCallGetStatsBlock)block;

    Swift

    func stats() async -> [TVOStatsReport]

    Parameters

    block

    The block to be invoked when the stats are available.

  • @brief Posts the feedback collected for this Call to Twilio.

    @discussion If TVOCallFeedbackScoreNotReported and TVOCallFeedbackIssueNotReported are passed, Twilio will report feedback was not available for this call.

    See

    TVOCallFeedbackScore

    See

    TVOCallFeedbackIssue

    Declaration

    Objective-C

    - (void)postFeedback:(TVOCallFeedbackScore)score
                   issue:(TVOCallFeedbackIssue)issue;

    Swift

    func postFeedback(_ score: TVOCallFeedbackScore, issue: TVOCallFeedbackIssue)

    Parameters

    score

    The quality score of the Call.

    issue

    The issue associated with the Call.

  • @brief Sends a user-defined message to the endpoints that subscribe to the user-defined messages of this call.

    @discussion The result will be raised to the TVOCallMessageDelegate provided in the TVOCallOptions on the same dispatch queue used for connecting the call. Dispatch main queue will be used if not specified.

    @discussion Sending a call message with content size that exceeds 10 KB or sending more than 10 call messages within one minute will result in the [TVOCallMessageDelegate call:didFailToSendMessage:error] callback.

    @discussion A call message with content that does not match the content type will not result in the [TVOCallMessageDelegate call:didFailToSendMessage:error] callback but will generate an error in your Twilio developer console. For example, a call message with content type “application/json” but with the content “Hello World”, which is not a valid JSON object, will result in such error.

    @discussion A subscription with a user-defined message callback is required prior to calling this method. Calling the [TVOCall sendMessage:] method without subscribing first will result in an error in your Twilio developer console.

    @discussion This feature is currently in Beta.

    Declaration

    Objective-C

    - (nonnull NSString *)sendMessage:(nonnull TVOCallMessage *)callMessage;

    Swift

    func send(_ callMessage: TVOCallMessage) -> String

    Parameters

    callMessage

    The TVOCallMessage object with the message and configuration.

    Return Value

    A unique identifier for tracking the message.

  • Unavailable

    A TVOCall object cannot be instantiated directly. See [TVOCallInvite acceptWithOptions:delegate:] or [TwilioVoiceSDK connectWithOptions:delegate:]

    @brief Call cannot be instantiated directly. Use [TVOCallInvite acceptWithOptions:delegate:] and [TwilioVoiceSDK connectWithOptions:delegate:].

    Declaration

    Objective-C

    - (null_unspecified instancetype)init;

CallKit

  • @brief A unique identifier for the Call.

    @discussion Use this UUID as an argument to CallKit methods. You can provide a UUID for outgoing calls using <[TwilioVoiceSDK connectWithOptions:delegate:]>. Calls created via <[TVOCallInvite acceptWithOptions:delegate:]> inherit their uuid from the Invite itself.

    Declaration

    Objective-C

    @property (nonatomic, strong, readonly, nullable) NSUUID *uuid;

    Swift

    var uuid: UUID? { get }