...
1. Импорт API. код
Code Block | ||||
---|---|---|---|---|
| ||||
#import <FPWCSApi2/FPWCSApi2.h> |
...
- URL WCS-сервера
- параметры SIP-аккаунта для совершения исходящих и приема входящих звонков
- имя серверного приложения defaultApp
Code Block | ||||
---|---|---|---|---|
| ||||
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]; 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-аккаунта
- вид для отображения локального видеопотока
- вид для отображения видеопотока, получаемого от собеседника
- параметры аудио и видео
Code Block | ||
---|---|---|
| ||
- (FPWCSApi2Call *)call {
FPWCSApi2Session *session = [FPWCSApi2 getSessions][0];
FPWCSApi2CallOptions *options = [[FPWCSApi2CallOptions alloc] init];
options.callee = _callee.input.text;
options.localDisplay = _videoView.local;
options.remoteDisplay = _videoView.remote;
options.localConstraints = [[FPWCSApi2MediaConstraints alloc] initWithAudio:YES video:YES];
options.remoteConstraints = [[FPWCSApi2MediaConstraints alloc] initWithAudio:YES video:YES];
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 | ||
---|---|---|
| ||
[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 | ||
---|---|---|
| ||
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 getLocalConstraints].video = [[FPWCSApi2VideoConstraints alloc] init];
[call setLocalDisplay:_videoView.local];
[call setRemoteDisplay:_videoView.remote];
[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 | ||
---|---|---|
| ||
- (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 hangup код
Code Block | ||
---|---|---|
| ||
- (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];
}
}
} |
8. Завершение входящего звонка.
FPWCSApi2Call hangup код
Code Block | ||
---|---|---|
| ||
UIAlertAction* hangupButton = [UIAlertAction actionWithTitle:@"Hangup" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { [call hangup]; }]; 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-аккаунта
- вид для отображения локального видеопотока
- вид для отображения видеопотока, получаемого от собеседника
- параметры аудио и видео
Code Block | ||||
---|---|---|---|---|
| ||||
- (FPWCSApi2Call *)call {
FPWCSApi2Session *session = [FPWCSApi2 getSessions][0];
FPWCSApi2CallOptions *options = [[FPWCSApi2CallOptions alloc] init];
options.callee = _callee.input.text;
options.localDisplay = _videoView.local;
options.remoteDisplay = _videoView.remote;
options.localConstraints = [[FPWCSApi2MediaConstraints alloc] initWithAudio:YES video:YES];
options.remoteConstraints = [[FPWCSApi2MediaConstraints alloc] initWithAudio:YES video:YES];
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 | ||||
---|---|---|---|---|
| ||||
[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 | ||||
---|---|---|---|---|
| ||||
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 getLocalConstraints].video = [[FPWCSApi2VideoConstraints alloc] init];
[call setLocalDisplay:_videoView.local];
[call setRemoteDisplay:_videoView.remote];
[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 | ||||
---|---|---|---|---|
| ||||
- (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 hangup код
Code Block | ||||
---|---|---|---|---|
| ||||
- (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];
}
}
} |
8. Завершение входящего звонка.
FPWCSApi2Call hangup код
Code Block | ||||
---|---|---|---|---|
| ||||
UIAlertAction* hangupButton = [UIAlertAction
actionWithTitle:@"Hangup"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[call hangup];
}];
[alert addAction:hangupButton]; |
...
FPWCSApi2Session disconnect код
Code Block | ||||
---|---|---|---|---|
| ||||
- (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]; } } |