I want to get phone call states in my app.
After some search I found CoreTelephony
framework. But that is deprecated in iOS 10. SO is there any other alternative available?
I also found CallKit
. A new framework in iOS 10. But didn't getting call states from same as I searched.
Asked
Active
Viewed 7,112 times
6

DeathStroke
- 124
- 1
- 9
-
What you want to convey by word "call states"? Can you please elaborate. – Mehul Thakkar Oct 13 '16 at 12:45
-
'dialing', 'disconnected', 'connected' like states for phone call. – DeathStroke Oct 13 '16 at 12:46
-
So you want some delegates, which gives you such states when any call transition have been happened, am i right? – Mehul Thakkar Oct 13 '16 at 12:47
-
I think, [this](https://developer.apple.com/reference/coretelephony/) `CTCall` and `CTCallCenter` is providing what kind of info I want. – DeathStroke Oct 13 '16 at 12:56
-
@DeathStroke If some of the answers helped you, mark one as accepted [What does it mean when an answer is "accepted"?](http://stackoverflow.com/help/accepted-answer) – Maxim Pavlov Feb 01 '17 at 12:14
-
is my answer helpful for you? – Saurabh Jain Aug 28 '17 at 15:43
5 Answers
12
import CallKit
into your AppDelegate
and add the following code:
// AppDelegate
var callObserver: CXCallObserver! // add property
// in applicationDidFinishLaunching...
callObserver = CXCallObserver()
callObserver.setDelegate(self, queue: nil) // nil queue means main thread
extension AppDelegate: CXCallObserverDelegate {
func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
if call.hasEnded == true {
print("Disconnected")
}
if call.isOutgoing == true && call.hasConnected == false {
print("Dialing")
}
if call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false {
print("Incoming")
}
if call.hasConnected == true && call.hasEnded == false {
print("Connected")
}
}
}

Brandon A
- 8,153
- 3
- 42
- 77
-
-
Yes this will work while your app is in the foreground or background. – Brandon A Apr 11 '17 at 05:53
-
it works in the background only for about 3 minutes and then does not work... I coded the following solution http://stackoverflow.com/questions/43044035/detecting-gsm-call-states-in-ios-10-and-notification-from-background-state where i show how i am calling it from background. It works for 3 minutes or so and then does not work. Have even placed a bounty on it that expired Placing another bounty now – ankit Apr 12 '17 at 06:43
-
@BrandonA just tagging you for attention :). Have started a new bounty worth 100 points again. – ankit Apr 12 '17 at 06:53
-
-
@littleali : It works for all calls, but the issue is you will never get caller details. You will get only udid – Mehul Thakkar Jul 25 '18 at 13:43
-
testing this code on swift 4.2, not working in background, if that case does not give any message in consolle if I drop the call from called device, but if I call back in foreground updates data. It seems does not register the change while in background, end going in background gives message "Could not load IOSurface for time string. Rendering locally instead." – biggreentree Nov 14 '18 at 13:58
7
You can try this code:
Create the instance of call observer
@property ( nonatomic ) CXCallObserver *callObserver;
Initiate the instance and set the delegate
_callObserver = [CXCallObserver new]; [_callObserver setDelegate:self queue:dispatch_get_main_queue()];
Add the call observer delegate
- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call{ if (call == nil || call.hasEnded == YES) { NSLog(@"CXCallState : Disconnected"); } if (call.isOutgoing == YES && call.hasConnected == NO) { NSLog(@"CXCallState : Dialing"); } if (call.isOutgoing == NO && call.hasConnected == NO && call.hasEnded == NO && call != nil) { NSLog(@"CXCallState : Incoming"); } if (call.hasConnected == YES && call.hasEnded == NO) { NSLog(@"CXCallState : Connected"); } }
In Swift 4.2:
var callObserver: CXCallObserver()
callObserver.setDelegate(self, queue: DispatchQueue.main)
func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
if call == nil || call.hasEnded == true {
print("CXCallState : Disconnected")
}
if call.isOutgoing == true && call.hasConnected == false {
print("CXCallState : Dialing")
}
if call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false && call != nil {
print("CXCallState : Incoming")
}
if call.hasConnected == true && call.hasEnded == false {
print("CXCallState : Connected")
}
}

Saurabh Jain
- 1,688
- 14
- 28
2
To be notified about phone call states, starting from iOS 10, you should use CXCallObserver
class and implement its CXCallObserverDelegate
protocol method, that is suggested in this answer:
- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call {
if (call.hasConnected) {
// perform necessary actions
}
}

Community
- 1
- 1

Maxim Pavlov
- 2,962
- 1
- 23
- 33
1
There is some delegate method available that indicate incoming and outgoing call status.

Shahabuddin Vansiwala
- 673
- 1
- 13
- 24
-
Thank you buddy, I don't know, I show same link but why didn't find protocol. – DeathStroke Oct 13 '16 at 13:01
-3
Apple does not allow you to access these informations though you can do so by using third party libraries but your app would be rejected at the time of submittion to App Store because apple does not allow to gain access to sensitive user information .

mukul
- 382
- 1
- 11
-
1This is not true, information about phone call states can be obtained via public API. Look at other answers. – Maxim Pavlov Feb 01 '17 at 11:46