Versions Compared

Key

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

Пример iOS-приложения для аудиозвонков

Работа с кодом примера

Для разбора кода возьмем версию примера PhoneMin, которая доступена для скачивания в сборке 2.5.2.

Класс для основного вида приложения: ViewController (заголовочный файл ViewController.h; файл имплементации ViewController.m).

1. Импорт API. код

Code Block
languagebash
#import <FPWCSApi2/FPWCSApi2.h>


2. Подключение к серверу.

FPWCSApi2 createSession, FPWCSApi2Session connect код
В параметрах сессии указываются:

  • URL WCS-сервера
  • параметры SIP-аккаунта для совершения исходящих и приема входящих звонков
  • имя серверного приложения defaultApp


Code Block
languagebash
FPWCSApi2SessionOptions *options = [[FPWCSApi2SessionOptions alloc] init];
options.urlServer = _connectUrl.text;
options.sipRegisterRequired = _sipRegRequired.control.isOn;
options.sipLogin = _sipLogin.input.text;
options.sipAuthenticationName = _sipAuthName.input.text;
options.sipPassword = _sipPassword.input.text;
options.sipDomain = _sipDomain.input.text;
options.sipOutboundProxy = _sipOutboundProxy.input.text;
options.sipPort = [NSNumber numberWithInteger: [_sipPort.input.text integerValue]];
options.appKey = @"defaultApp";
NSError *error;
if (!options.sipLogin.length || !options.sipAuthenticationName.length || !options.sipPassword.length ||
!options.sipDomain.length || !options.sipOutboundProxy.length || options.sipPort.integerValue == 0) {
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:@"All Sip Credentials is required"
message:error.localizedDescription
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction* okButton = [UIAlertAction
actionWithTitle:@"Ok"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self onDisconnected];
}];

[alert addAction:okButton];
[self presentViewController:alert animated:YES completion:nil];
return nil;
}
session = [FPWCSApi2 createSession:options error:&error];
if (error) {
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:@"Failed to connect"
message:error.localizedDescription
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction* okButton = [UIAlertAction
actionWithTitle:@"Ok"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self onDisconnected];
}];

[alert addAction:okButton];
[self presentViewController:alert animated:YES completion:nil];
return nil;
}
...
[session connect];


3. Исходящий звонок.

FPWCSApi2Session createCall, FPWCSApi2Call call код

При создании звонка в метод createCall передаются параметры:

  • имя вызываемого SIP-аккаунта
  • дополнительные параметры SIP INVITE запроса, введенные пользователем


Code Block
languagebash
- (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
// options.localConstraints = [[FPWCSApi2MediaConstraints alloc] initWithAudio:NO video:NO];
// options.remoteConstraints = [[FPWCSApi2MediaConstraints alloc] initWithAudio:YES video:NO];
NSError *error;
call = [session createCall:options error:&error];
if (!call) {
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:@"Failed to create call"
message:error.localizedDescription
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction* okButton = [UIAlertAction
actionWithTitle:@"Ok"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self toCallState];
}];

[alert addAction:okButton];
[self presentViewController:alert animated:YES completion:nil];
return nil;
}

[call on:kFPWCSCallStatusBusy callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toCallState];
}];

[call on:kFPWCSCallStatusFailed callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toCallState];
}];

[call on:kFPWCSCallStatusRing callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toHangupState];
}];

[call on:kFPWCSCallStatusHold callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self changeViewState:_holdButton enabled:YES];
}];

[call on:kFPWCSCallStatusEstablished callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toHangupState];
[self changeViewState:_holdButton enabled:YES];
}];

[call on:kFPWCSCallStatusFinish callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toCallState];
}];

[call call];
return call;
}



4. Получение от сервера события, сигнализирующего о входящем звонке

FPWCSApi2Session onIncomingCallCallback код

Code Block
languagebash
[session onIncomingCallCallback:^(FPWCSApi2Call *rCall) {
call = rCall;

[call on:kFPWCSCallStatusBusy callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toCallState];
}];

[call on:kFPWCSCallStatusFailed callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toCallState];
}];

[call on:kFPWCSCallStatusRing callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toHangupState];
}];

[call on:kFPWCSCallStatusHold callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self changeViewState:_holdButton enabled:YES];
}];

[call on:kFPWCSCallStatusEstablished callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toHangupState];
[self changeViewState:_holdButton enabled:YES];
}];

[call on:kFPWCSCallStatusFinish callback:^(FPWCSApi2Call *call){
[self changeCallStatus:call];
[self toCallState];
[self dismissViewControllerAnimated:YES completion:nil];
}];
...
}];


5. Ответ на входящий звонок.

FPWCSApi2Call answer код

Code Block
languagebash
alert = [UIAlertController
alertControllerWithTitle:[NSString stringWithFormat:@"Incoming call from '%@'", [rCall getCallee]]
message:error.localizedDescription
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction* answerButton = [UIAlertAction
actionWithTitle:@"Answer"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[call answer];
}];

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

[alert addAction:hangupButton];
[self presentViewController:alert animated:YES completion:nil];


6. Удержание звонка.

FPWCSApi2Call hold, unhold код

Code Block
languagebash
- (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 hold];
[_holdButton setTitle:@"UNHOLD" forState:UIControlStateNormal];
}
}
}


7. Отправка тонального сигнала

FPWCSApi2Call sendDTMF код

Code Block
languagebash
- (void)dtmfButton:(UIButton *)button {
if (call) {
[call sendDTMF:_dtmf.input.text type:kFPWCSCallDTMFRFC2833];
}
}


8. Завершение исходящего звонка.

FPWCSApi2Call hangup код

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


9. Завершение входящего звонка.

FPWCSApi2Call hangup код

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

[alert addAction:hangupButton];


10. Закрытие соединения.

FPWCSApi2Session disconnect код


Code Block
languagebash
- (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];
}
} else {
//todo check url is not empty
[self changeViewState:_connectUrl enabled:NO];
[self changeViewState:_sipLogin.input enabled:NO];
[self changeViewState:_sipAuthName.input enabled:NO];
[self changeViewState:_sipPassword.input enabled:NO];
[self changeViewState:_sipDomain.input enabled:NO];
[self changeViewState:_sipOutboundProxy.input enabled:NO];
[self changeViewState:_sipRegRequired.control enabled:NO];
[self changeViewState:_sipPort.input enabled:NO];
[self connect];
}
}