iOS 获取通话时间

今天产品提了一个需求,让面向商家的 app 用户只能通过我们的 app 拨打电话,并且记录通话时间。

iOS 拨打电话必须通过系统的页面,肯定能看到号码,那么接下来很容易就想到,对它看到的号码做一个特殊处理就可以,就像滴滴、饿了么之类一样。

至于通话时间,没法直接获取通话记录信息,但是如果能监听到通话状态的改变,我们自己做一个计算就可以了。

所以产品功能就转化为两个功能--隐藏电话和监听通话状态。

隐藏号码

饿了么在下单的时候是可以勾选隐藏号码的,这样快递员送餐时打来的电话是一个与普通手机号格式不一样的号码,搜索一番后发现这是类似与 回拨电话 的功能,所来也简单,在每单交易中,将用户手机发给服务器,服务器返回一个特殊号码并返回给商家,商家拨打这个号码会在呼叫中心中导向这个用户,交易结束后回收这个号码。提供这个服务的公司也很多。

原理图大概如下
Image

监听通话状态

iOS7 以前开放了一个新框架 CoreTelephony ,可以满足需求,甚至不用获取通信录等特殊权限,可以无感知的监听。
具体代码很简单

导入框架

#import <CoreTelephony/CTCallCenter.h>
#import <CoreTelephony/CTCall.h>

定义变量

@property (nonatomic,strong) CTCallCenter *callCenter;

监听状态

    @weakify(self);
    self.callCenter.callEventHandler = ^(CTCall *call){
        @strongify(self);
        __block NSTimeInterval start;
        dispatch_async(dispatch_get_main_queue(), ^{
            if ([call.callState isEqualToString:CTCallStateDisconnected]){
                NSLog(@"Call has been disconnected");
              // 获取挂断时间,减去接通时间即为通话时间
            }else if ([call.callState isEqualToString:CTCallStateConnected]){
                NSLog(@"Call has just been connected");
                // 记录接通时间

            }else if([call.callState isEqualToString:CTCallStateIncoming]){
                NSLog(@"Call is incoming");

            }else if ([call.callState isEqualToString:CTCallStateDialing]){
                NSLog(@"call is dialing");

            }else{
                NSLog(@"Nothing is done");
            }
        });

    };

谢谢阅读。


我是 Wythe,iOS 开发者,对其他技术也有好奇。公众号 WytheTalk,从一个程序员的角度看世界,主要是技术分享,也有对互联网各种事的观点。欢迎关注。

WytheTalk.jpg

最后,为了能被更方便得搜索到,加一些关键词
iOS 隐藏号码、滴滴隐藏手机号、iOS 获取通话时间、iOS 监听手机状态、Uber 隐藏手机号