# Realize One-to-One Voice Calling

This guide introduces how to implement one-to-one voice calls. The API call sequence of one-to-one calls is shown in the figure below:

../../../../_images_en/1-1workflowios.jpg

# Initialize

Call JCMediaDevice create (opens new window) and JCCall create (opens new window) to initialize the modules needed for one-to-one calling:

//Initialize
-(bool)initialize {
    //1. Media class
    JCMediaDevice *mediaDevice = [JCMediaDevice create:client callback:self];
    //2. Call class
    JCCall *call = [JCCall create:client mediaDevice:mediaDevice callback:self];
    ...
}

Among them:

  • The callback in the JCMediaDevice create is the proxy object of the JCMediaDeviceCallback (opens new window) protocol, which is used to notify the upper layer of media device related events. Therefore, you need to specify the proxy object of callback first, and then implement the JCMediaDeviceCallback in the proxy object.

The main methods in the JCMediaDeviceCallback are as follows:

//Camera changes
-(void)onCameraUpdate;

//Audio output changes
-(void)onAudioOutputTypeChange:(NSString*)audioOutputType;

//Sound interruption recovery
-(void)onAudioInerruptAndResume:(BOOL)interrupt;
  • The callback in the JCCall create is a proxy object of the ||JCCallCallback| protocol, which is used to notify the upper layer of the call-related events. Therefore, you need to specify the proxy object of callback first, and then implement JCCallCallback in the proxy object.

The main methods in the JCCallCallback are as follows:

//This callback triggers when the callItem is added
-(void)onCallItemAdd:(JCCallItem* __nonnull)item;

//This callback triggers when the call is removed
-(void)onCallItemRemove:(JCCallItem* __nonnull)item reason:(JCCallReason)reason description:(NSString * __nullable)description;

//The callback of call status update (When the upper layer receives this callback, you can obtain all the information and status of the call according to the JCCallItem object, thereby updating the call related UI)
-(void)onCallItemUpdate:(JCCallItem* __nonnull)item changeParam:(JCCallChangeParam * __nullable)changeParam;

# Make a call

Call call (opens new window) to initiate a video call, the parameters that need to be filled are:

  • userID Fill in the user ID of the other party.

  • video Select whether to call a video call, and true means to make a video call, while false means to make a voice call.

  • extraParam is a custom pass-through string, which can be obtained through the extraParam property in the JCCallItem object.

// Initiate a voice call
[call call:@"userID" video:false extraParam:@"custom pass-through string"];

After dialing the call, both the caller and the callee will receive the callback onCallItemAdd (opens new window) for the new call, and the call status will change to JCCallStatePending at this time. You can implement the onCallItemAdd (opens new window) method in the upper layer and handle the related logic:

// Receive a new call callback
-(void)onCallItemAdd:(JCCallItem* __nonnull)item {
    // Business logic
    if (item.direction == JCCallDirectionIn) {
        // If it is an incoming call
        ...
    } else {
        // If it is an outgoing call
        ...
    }
}

TIP

If the caller wants to cancel the call, he/she can go directly to the hang up part. After calling the hang up interface, the call status becomes the JCCallStateCancel.

# Answer a call

  1. After the caller initiates the call successfully, the called party will receive the onCallItemAdd (opens new window) callback. At this time, the video and direction properties of the JCCallItem (opens new window) object in the callback can be used to determine whether it is a video call or a voice call, so as to make corresponding processing:

    -(void)onCallItemAdd:(JCCallItem* __nonnull)item {
        // 1. If it is an incoming video call and it is ringing
        if (item && item.direction == JCCallDirectionIn && !item.video) {
            // 2. Make corresponding processing, such as "ringing" on the interface
            ...
        }
    }
    
  2. Call answer (opens new window) to answer calls, Voice calls can only be answered by voice:

    // Answer the call
    [call answer:item video:false];
    

After the call is answered, the call status changes to JCCallStateConnecting.

TIP

If you want to reject the call at this time, you can go directly to the hang up part. After calling the hang up interface, the call state becomes JCCallStateCanceled.

# Hang up a call

Both the calling party and the called party can hang up the call.

  1. First call getActiveCallItem (opens new window) to get the currently active call object.

  2. After obtaining the current active call object, call term (opens new window) to hang up the current active call:

    // 1. Get the current active call
    JCCallItem *item = [call getActiveCallItem];
    // 2. Hang up the current active call
    [call term:item reason:JCCallReasonNone description:@"the caller hangs up"];
    

After hanging up the call, the onCallItemRemove in JCCallCallback will be triggered, and the call state will change to JCCallStateOk.