Differentiate active call is cellular call or voip call - ios

We are building voip based application and we have one scenario where we have to identify whether active call is voip call or cellular call(cs call). Before iOS10 and before callkit we used to check through CTCallCenter like below code snap.
- (BOOL)nativeCallPresent
//This only works before callkit and ios 10,
//If iOS is greater or equal 10 then it always return yes for CS and voip call both.
CTCallCenter * callcenter = [[CTCallCenter alloc] init];
BOOL nativeCallPresent = ([callcenter currentCalls] != nil);
return nativeCallPresent;
}
I checked in apple callkit but did not find any way to check that active call is cellular call or voip call.
Can somebody from apple or developer community can help here?
Thanks.

Related

Sinch SDK - iOS app does not receive immediate callback when callee reject the call

I integrated Sinch SDK into iOS application (Capacity plugin which works under ionic).
Main use case so far is to make call from App to phone.
I followed instructions from here: https://developers.sinch.com/docs/in-app-calling/getting-started/ios/create-app/ and everything works correctly - I can call from the app to phones using Sinch platform.
The problem which I noticed is when callee rejects the call then app does not receive immediate notification about it. Sometimes notification (func callDidEnd(_ call: SinchRTC.SinchCall)) is triggered after some delay (10-20s). However sometimes when callee rejects the call app is still calling and second connection appears on callee's phone - then when second time callee rejects the call app correctly receive callback about it and close the connection.
Do you have any hints what can be the issue here?
We will review the tutorial to see if the issue can be replicated.
However using the VideoCallKitSwift Swift sample you can change the following to the sinch client on start and call invocation to make a PSTN call:
In CallKitMediator
add the cli:<YOURCLI> after userId in the SinchRTC.client (In this case I have put a placeholder +4100000000 in the cli)
From
do {
self.client = try SinchRTC.client(withApplicationKey: APPLICATION_KEY,
environmentHost: ENVIRONMENT_HOST,
userId: userId)
To
do {
self.client = try SinchRTC.client(withApplicationKey: APPLICATION_KEY,
environmentHost: ENVIRONMENT_HOST,
userId: userId,
cli:"+4100000000")
In CallKitMediator+CXProviderDelegate Here remove the withId: and change the client method to callPhoneNumber instead of videoCallToUser
From
let callResult = self.client!.callClient.videoCallToUser(withId: action.handle.value)
To
let callResult = self.client!.callClient.callPhoneNumber(action.handle.value)
Testing to a PSTN connection via this method yields no delay in the callDidEnd. If your issues persist, I would recommend to open a ticket with Sinch support who can analyse the PSTN leg of the call for you.

How to detect other VOIP call (iOS)?

I am working on an app that allows video calls using an SDK that utilises webRTC on iOS.
Intended functionality is that if another call is instantiated after my app has instantiated a call, I want my app to mute audio in both directions in my call until that call has ended, in which case audio is restored.
I have encountered a problem where I want to detect other calls that make VOIP calls (for example WeChat and Facebook Messenger).
In the case of WeChat I have solved this exploiting that it interrupts the shared audio session (of AVAudioSession). The code that handles this is as follows:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector
(audioSessionInterrupted:)
...
name:AVAudioSessionInterruptionNotification object:nil];
- (void) audioSessionInterrupted:(NSNotification*)notification
{
if(notification.name == AVAudioSessionInterruptionNotification)
{
NSDictionary* userInfo = notification.userInfo;
int result = userInfo[AVAudioSessionInterruptionTypeKey];
if(result == AVAudioSessionInterruptionTypeBegan)
{
[[AVAudioSession sharedInstance] setActive:NO error:nil];
[self setAudioEnabled:NO];
}
else if (result == AVAudioSessionInterruptionTypeEnded)
{
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[self setAudioEnabled:YES];
}
}
}
However, for Facebook Messenger, this method is never called. I speculate from this that WeChat may be demanding exclusive access to the shared audio session (and thus causing an interruption of the audio session with my app) whereas Facebook Messenger chooses to mix its audio, or uses a separate audio session when a call is instantiated.
My question is does there exist another way of detecting other VOIP calls, possibly using the CallKit framework? My app uses CallKit to prompt user for incoming calls, and records ingoing/outgoing calls in the iOS phone log.
I would recommend checking all current native calls. All calls that are registered through CallKit are also considered native calls and trigger a call on this object, from CoreTelephony:
CTCallCenter *callCenter = [[CTCallCenter alloc] init];
callCenter.callEventHandler = ^(CTCall* call) {
//Native call changes are triggered here
};
For detecting VOIP calls from applications that do not support CallKit, this is harder. A possibility is listening to changes to the AVAudioUnit.

iOS - Can I open my VoIP app on answering call using Callkit?

I'm planning to create an iOS VoIP app(not made any iOS app before). I was reading about Callkit in IOS by which one can make his app receive phone call through iPhone native call screen.
I read Callkit api here where it is mentioned that one can know if a call is answered.
Going through this tutorial and here is the code which detects the call is answered:
-(void)reportIncomingCallWithHandle:(NSString *)handle
success:(void (^)())success
failure:(void (^)(NSError * error))failure {
CXCallUpdate *update = [self newCallUpdateWithHandle:handle];
self.callId = [NSUUID UUID];
[self.provider reportNewIncomingCallWithUUID:self.callId update:update completion:^(NSError * _Nullable error) {
if (error) {
if (failure) failure(error);
} else {
if (success) {
success();
}
}
}];
}
See the success block. So is there is a way to open my app when this success block executed? Or can I override default buttons on caller screen to open my app?
I know there is no way to open an app on receiving any kind of notification, or event trigger. So thought may be there is some way if I can do the same using Callkit
I Googled everything but found no clue regarding my above queries. Please help me if it is possible or not.
I encountered the same issue. The behavior varies depending on if the device is locked or not.
Locked: System calling screen appears. You can run the app in the background including view transitions. However, the user will only see the system calling screen although your app is kind of presented underneath the view. As the device is locked, deep links does not work as well.
Unlocked: Calling screen is the same but once the user answers the call, the app will be presented.
As you may know, we can change the icon of the button on the calling screen which opens the app, and that's the best we can do as of now.
You can not open your own VoIP app or custom UI of your App from CallKit. Use can use it in a way as Whatsapp does.
Means you can awake your app from background without using local notification. And OS will show the default incoming screen. You need not to handle anything during call. CallKit is specially made for enhancing VoIP apps by receiving calls in background, by making outgoing calls, by managing Call directory and blocking of users.

Detectiing a incoming Facetime call in ios

Is there anyway to detect an incoming Facetime call in ios. I tried CTCallCenter but it seems like it only works with cellular calls and not facetime calls.. I am using following code to detect facetime call but no success.
self.callCenter = [[CTCallCenter alloc] init];
self.callCenter.callEventHandler = ^(CTCall* myCall) {
NSString *call = myCall.callState;
if ([call isEqualToString:CTCallStateDisconnected])
NSLog(#"Call has been disconnected");
else if([call isEqualToString:CTCallStateDialing])
NSLog(#"Call start");
else if ([call isEqualToString:CTCallStateConnected])
NSLog(#"Call has just been connected");
else if([call isEqualToString:CTCallStateIncoming])
NSLog(#"Call is incoming");
else
NSLog(#"None");
};
Any help?
You don't need an app-specific detection for every app that needs pausing your playback. You should use AVAudioSession to detect any kind of audio interruption and notify your music player to pause.
See this image and explanation from Apple's documentation:
AVAudioSession gives you control your app’s audio behavior. You can:
Select the appropriate input and output routes for your app
Determine how your app integrates audio from other apps
Handle interruptions from other apps
Automatically configure audio for the type of app your are creating
So, you can use the AVAudioSession API to handle any incoming calls that can be a cellular call or a FaceTime one, or even anything third-party like Viber, Tango, Line, etc.
You can also check the AddMusic sample app to see how it's implemented.

Objective-c make phone call in background mode

I have to solve the following problem in objective-c:
Application in background
For an event, i need to call a specific phone number on the iPhone while it is still in background
As i see my logs, the phone call method will be called, but the phone number not dialing by the iOS.
Here is the action method:
//------------------------------------------------//
- (IBAction)actionCall:(id)sender
{
id<ICallModel> _AutoCall = [self retrieveAutoCall];
if(_AutoCall != nil)
{
DDLogDebug(#"RESCUE CALL: %#",_AutoCall.PhoneNumber);
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"tel:%#",_AutoCall.PhoneNumber]]];
}
[self actionCancel:nil];
}
//------------------------------------------------//
If the application is active, then it works perfectly.
I've added the proper background modes too.
Is it possible some way to achieve this flow?
Thanks,
Tom
Apple doesn't allow you to start calls if your app is running in the background.
What you could do is using Local Notifications to make the user returning to your app.
Once your app is back in the foreground it could start the call.

Resources