get phone call states in iOS 10
Asked Answered
M

5

6

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.

Melancon answered 13/10, 2016 at 12:41 Comment(6)
What you want to convey by word "call states"? Can you please elaborate.Athalie
'dialing', 'disconnected', 'connected' like states for phone call.Melancon
So you want some delegates, which gives you such states when any call transition have been happened, am i right?Athalie
I think, this CTCall and CTCallCenter is providing what kind of info I want.Melancon
@Melancon If some of the answers helped you, mark one as accepted What does it mean when an answer is "accepted"?Croom
is my answer helpful for you?Treblinka
S
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")
        }
    }
}
Shipboard answered 13/3, 2017 at 0:26 Comment(7)
can we do this in background state?Solemnize
Yes this will work while your app is in the foreground or background.Shipboard
it works in the background only for about 3 minutes and then does not work... I coded the following solution #43044535 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 nowGypsum
@BrandonA just tagging you for attention :). Have started a new bounty worth 100 points again.Gypsum
This is just for VOIP call or it also works for cellular calls?Litta
@Litta : It works for all calls, but the issue is you will never get caller details. You will get only udidAthalie
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."Duodenary
T
7

You can try this code:

  1. Create the instance of call observer

    @property ( nonatomic ) CXCallObserver *callObserver;
    
  2. Initiate the instance and set the delegate

    _callObserver = [CXCallObserver new];
            [_callObserver setDelegate:self queue:dispatch_get_main_queue()];
    
  3. 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")
    }
}
Treblinka answered 29/11, 2016 at 13:28 Comment(0)
C
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
    }
}
Croom answered 14/10, 2016 at 17:4 Comment(0)
M
1

There is some delegate method available that indicate incoming and outgoing call status.

See : https://developer.apple.com/reference/callkit

Myungmyxedema answered 13/10, 2016 at 12:56 Comment(1)
Thank you buddy, I don't know, I show same link but why didn't find protocol.Melancon
C
-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 .

Concordant answered 13/10, 2016 at 12:56 Comment(1)
This is not true, information about phone call states can be obtained via public API. Look at other answers.Croom

© 2022 - 2024 — McMap. All rights reserved.