Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Table of Contents

Overview

The example shows how to make an audio SIP call with iOS SDK

On the screenshot below the example is displayed before a call will be established.

...

SIP connection is established/closed when Connect/Disconnect button is clicked.
Call is placed/terminated when Call/Hangup button is clicked, and put on hold/retrieve when Hold/Unhold button is clicked.

Analyzing the code of the example

To analyze the code, let's take PhoneMin take PhoneMin example, which can be downloaded with corresponding build  2.5.2.is availabe on GitHub.

View class for the main view of the application: ViewController (header file file ViewController.h; implementation file file ViewController.m).

1. Import of API code

Code Block
languagecpp
themeRDark
#import <FPWCSApi2/FPWCSApi2.h>

2.  Connection to the server.

FPWCSApi2.createSession, FPWCSApi2Session connect .connect code

FPWCSApi2SessionOptions object with the following parameters is passed to createSession() method

...

3. Outgoing call.

FPWCSApi2Session.createCall, FPWCSApi2Call call .call code

The next following parameters are passed to createCall() method:

...

Code Block
languagecpp
themeRDark
- (FPWCSApi2Call *)call {
    FPWCSApi2Session *session = [FPWCSApi2 getSessions][0];
    FPWCSApi2CallOptions *options = [[FPWCSApi2CallOptions alloc] init];
    NSString *parameters = _inviteParameters.input.text;
    if (parameters && [parameters length] > 0) {
        NSError* err = nil;
        parameters = [parameters stringByReplacingOccurrencesOfString:@""" withString:@"\""];
        NSMutableDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[parameters dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&err];
        if (err) {
            NSLog(@"Error converting JSON Invite parameters to dictionary %@, JSON %@", err, parameters);
        } else {
            options.inviteParameters = dictionary;
        }
    }
    options.callee = _callee.input.text;
    //used for only recv audio
//...
    NSError *error;
    options.localConstraintscall = [[FPWCSApi2MediaConstraints alloc] initWithAudio:NO video:NOsession createCall:options error:&error];
//    options.remoteConstraints =...
    [[FPWCSApi2MediaConstraintscall alloccall] initWithAudio:YES video:NO];
    NSError *error;;
    return call;
}

4. Receiving the event on incoming call

FPWCSApi2Session.onIncomingCallCallback code

Code Block
languagecpp
themeRDark
[session onIncomingCallCallback:^(FPWCSApi2Call *rCall) {
    call = [session createCall:options error:&error];rCall;
        
    [call on:kFPWCSCallStatusBusy callback:^(FPWCSApi2Call *call){
    ...
    [callself changeCallStatus:call];
      return call;
}

4. Receiving the event on incoming call

FPWCSApi2Session onIncomingCallCallback code

Code Block
languagecpp
themeRDark
[session onIncomingCallCallback:^(FPWCSApi2Call *rCall) {
    call = rCall  [self toCallState];
    }];
        
    [call on:kFPWCSCallStatusBusykFPWCSCallStatusFailed callback:^(FPWCSApi2Call *call){
        [self changeCallStatus:call];
        [self toCallState];
    }];
        
    [call on:kFPWCSCallStatusFailedkFPWCSCallStatusRing callback:^(FPWCSApi2Call *call){
        [self changeCallStatus:call];
        [self toCallStatetoHangupState];
    }];
        
    [call on:kFPWCSCallStatusRingkFPWCSCallStatusHold callback:^(FPWCSApi2Call *call){
        [self changeCallStatus:call];
        [self toHangupStatechangeViewState:_holdButton enabled:YES];
    }];
        
    [call on:kFPWCSCallStatusHoldkFPWCSCallStatusEstablished callback:^(FPWCSApi2Call *call){
        [self changeCallStatus:call];
        [self toHangupState];
        [self changeViewState:_holdButton enabled:YES];
    }];
        
    [call on:kFPWCSCallStatusEstablishedkFPWCSCallStatusFinish callback:^(FPWCSApi2Call *call){
        [self changeCallStatus:call];
        [self toHangupStatetoCallState];
        [self changeViewStatedismissViewControllerAnimated:_holdButtonYES enabledcompletion:YESnil];
    }];
        
    [call on:kFPWCSCallStatusFinish callback:^(FPWCSApi2Call *call){
...
}];

5. Answering incoming call

FPWCSApi2Call.answer code

Code Block
languagecpp
themeRDark
alert = [UIAlertController
         [self changeCallStatus:call];
        [self toCallState];
        [self dismissViewControllerAnimated:YES completion:nil];
 alertControllerWithTitle:[NSString stringWithFormat:@"Incoming call from '%@'", [rCall getCallee]]
                         }];
    message:error...
}];

5. Answering incoming call.

FPWCSApi2Call answer code

Code Block
languagecpp
themeRDark
alert = [UIAlertController
localizedDescription
                             preferredStyle:UIAlertControllerStyleAlert];
   alertControllerWithTitle:[NSString stringWithFormat:@"Incoming call from '%@'", [rCall getCallee]]
 
UIAlertAction* answerButton = [UIAlertAction
                               message:error.localizedDescriptionactionWithTitle:@"Answer"
                             preferredStyle:UIAlertControllerStyleAlert];
  style:UIAlertActionStyleDefault
           
UIAlertAction* answerButton = [UIAlertAction
                 handler:^(UIAlertAction * action) {
           actionWithTitle:@"Answer"
                        [call answer];
      style:UIAlertActionStyleDefault
                         }];
      handler:^(UIAlertAction * action) {
   
[alert addAction:answerButton];
UIAlertAction* hangupButton = [UIAlertAction
                                [call answer];actionWithTitle:@"Hangup"
                               }];
style:UIAlertActionStyleDefault
          
[alert addAction:answerButton];
UIAlertAction* hangupButton = [UIAlertAction
                 handler:^(UIAlertAction * action) {
           actionWithTitle:@"Hangup"
                        [call hangup];
      style:UIAlertActionStyleDefault
                         }];
      handler:^(UIAlertAction * action) {
                                   [call hangup[alert addAction:hangupButton];
[self presentViewController:alert animated:YES completion:nil];

6. Call hold and retrieve

FPWCSApi2Call.hold, unhold code

Code Block
languagecpp
themeRDark
- (void)holdButton:(UIButton *)button {
    [self changeViewState:button enabled:NO];
    if ([button.titleLabel.text              }];isEqualToString:@"UNHOLD"]) {
        
[alert addAction:hangupButton];
[self presentViewController:alert animated:YES completion:nil];

6. Call hold and retrieve.

FPWCSApi2Call hold, unhold code

Code Block
languagecpp
themeRDark
- (void)holdButton:(UIButton *)button {
    [self changeViewState:button enabled:NO];
    if ([button.titleLabel.text isEqualToString:@"UNHOLD"])if (call) {
            [call unhold];
            [_holdButton setTitle:@"HOLD" forState:UIControlStateNormal];
        }
    } else {
        if (call) {
            [call unholdhold];
            [_holdButton setTitle:@"HOLDUNHOLD" forState:UIControlStateNormal];
        }
    }
} else

7. DTMF sending

FPWCSApi2Call.sendDTMF code

Code Block
languagecpp
themeRDark
- (void)dtmfButton:(UIButton *)button {
        if (call) {
            [call hold];
            [_holdButton setTitle:@"UNHOLD" forState:UIControlStateNormal];
        }sendDTMF:_dtmf.input.text type:kFPWCSCallDTMFRFC2833];
    }
}

7. DTMF sending

FPWCSApi2Call sendDTMF 8. Switching from the voice speaker to the loud speaker

FPWCSApi2Call.setLoudspeakerStatus code

Code Block
languagecpp
themeRDark
- (void)dtmfButtonuseLoudSpeakerValueChanged:(UIButton *id)buttonsender {
    if (call) {
        [call sendDTMFsetLoudspeakerStatus:_dtmfuseLoudSpeaker.inputcontrol.textisOn typewithError:kFPWCSCallDTMFRFC2833nil];
    }
}

89. Outgoing call hangup.

FPWCSApi2Call hangup .hangup code

Code Block
languagecpp
themeRDark
- (void)callButton:(UIButton *)button {
    [self changeViewState:button enabled:NO];
    if ([button.titleLabel.text isEqualToString:@"HANGUP"]) {
        if ([FPWCSApi2 getSessions].count) {
            [call hangup];
        } else {
            [self toCallState];
        }
        ...
    }
}

910. Incoming call hangup.

FPWCSApi2Call hangup .hangup code

Code Block
languagecpp
themeRDark
UIAlertAction* hangupButton = [UIAlertAction
                               actionWithTitle:@"Hangup"
                               style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction * action) {
                                   [call hangup];
                               }];
        
[alert addAction:hangupButton];

1011. Disconnection.

FPWCSApi2Session disconnect .disconnect code

Code Block
languagecpp
themeRDark
- (void)connectButton:(UIButton *)button {
    [self changeViewState:button enabled:NO];
    if ([button.titleLabel.text isEqualToString:@"DISCONNECT"]) {
        if ([FPWCSApi2 getSessions].count) {
            FPWCSApi2Session *session = [FPWCSApi2 getSessions][0];
            NSLog(@"Disconnect session with server %@", [session getServerUrl]);
            [session disconnect];
        } else {
            NSLog(@"Nothing to disconnect");
            [self onDisconnected];
        }
        ...
    }
}