25

I have look around and all I can find is checking the callState of CTCallCenter. However, this works by listening to an event - which depending on whether the application is active/suspended/resumed the event can be raised at different time.

What I need is rather than listening to event and got told when call is connected, I want to decide myself when to ask if the call is connected.

Use case: When phone call is connected - user knows and will always click on the app icon, which will open the app. At this time I just want to run a quick function to check if currently on call or not.

Is this even possible?

ThomasW
  • 16,981
  • 4
  • 79
  • 106
friend
  • 1,909
  • 2
  • 21
  • 28

4 Answers4

28

The CTCallCenter object has a currentCalls property which is an NSSet of the current calls. If there is a call then the currentCalls property should be != nil.

If you want to know if any of the calls is actually connected, then you'll have to iterate through the current calls and check the callState to determine if it is CTCallStateConnected or not.

ThomasW
  • 16,981
  • 4
  • 79
  • 106
27
#import <CoreTelephony/CTCallCenter.h>
#import <CoreTelephony/CTCall.h>

-(bool)isOnPhoneCall {
    /*

     Returns TRUE/YES if the user is currently on a phone call

     */

    CTCallCenter *callCenter = [[[CTCallCenter alloc] init] autorelease];
    for (CTCall *call in callCenter.currentCalls)  {
        if (call.callState == CTCallStateConnected) {
            return YES;
        }
    }
    return NO;
}
AlBeebe
  • 8,101
  • 3
  • 51
  • 65
6

Thanks for the answer ThomasW. I thought I would also post the code.

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    CTCallCenter *ctCallCenter = [[CTCallCenter alloc] init];
    if (ctCallCenter.currentCalls != nil) 
    {
        NSArray* currentCalls = [ctCallCenter.currentCalls allObjects];
        for (CTCall *call in currentCalls)
        {   
            if(call.callState == CTCallStateConnected)
            {
                // connected
            }
        }
    }
}
friend
  • 1,909
  • 2
  • 21
  • 28
  • 3
    You could shorten this code a lot by using fast enumeration: `for (CTCall *call in ctCallCenter.currentCalls) {...}`. You don't need to check for `nil` or convert the set to an array. – omz Jun 08 '12 at 06:49
  • could you suggest your code then omz? i would be more than happy to upvote your answer if it will simply bong's post and be a lot more efficient and effective.. cheers omz. – Pavan Aug 08 '12 at 21:01
  • exactly what i needed! upvoted! @AlBeebe: currentCalls is used in the next line. – rockstarberlin Mar 29 '13 at 02:59
2

I was having the same problem, but I think that the correct way to do this from iOS 10 is:

func checkForActiveCall() -> Bool {
    for call in CXCallObserver().calls {
        if call.hasEnded == false {
            return true
        }
    }
    return false
}
JPetric
  • 3,838
  • 28
  • 26