Board logo

标题: CallKit的研究 [打印本页]

作者: look_w    时间: 2019-2-19 14:55     标题: CallKit的研究

CallKit的研究

最近帮一个朋友做一个app,他有一个需求,希望来电话时候,可以在来电界面显示来电的相关信息,信息就来自于app内(app内维护一个企业通讯录,来电话的时候即使这个号码不在系统通讯录内,也可以通过app的通讯录查出来)。android肯定是没问题的,再iOS10 之前是不可想的,不过现在iOS 10 开放了CallKit的N多权限,我就研究了下。

资料查阅官网文档

demo地址
认证来电呼叫(Identifying Incoming Callers)

app可以创建一个呼叫目录扩展(Call Directory Extension)来认证或者屏蔽来电。字面意思来看,认证来电这项貌似我们的要求匹配。
注意:电话号码需要用CXCallDirectoryPhoneNumber(int_64类型)来承载,同时包含了电话号码和国家码,中国是86,没有+。

iPhone收到来电后,系统首先查询系统通讯录。如果没有匹配信息,再去查找app的Call Directory。找到了,就会显示相关信息。
场景:你的某个社交app的好友给你打来电话,但是你根本就没存他的号码,一直都是用app的聊天私信之类的联系。这时候来电显示就能显示出相关信息,而不是纯陌生号码了。
操作
1、新建Call Directory Extension

新建一个target,选择Application Extensions - Call Directory Extension,注意和主target的bundle id要区分出来。
2、补充代码

创建完后,工程下会多出一个目录,自动生成CXCallDirectoryProvider子类,根据里面的代码进行补充。

    - (void)beginRequestWithExtensionContextCXCallDirectoryExtensionContext *)context {
        
        NSDictionary<NSNumber *, NSString *> *labelsKeyedByPhoneNumber = @{@(8613511111111) "我是周杰伦"};
        
        for (NSNumber *phoneNumber in [labelsKeyedByPhoneNumber.allKeys sortedArrayUsingSelectorselector(compare]) {
            NSString *label = labelsKeyedByPhoneNumber[phoneNumber];
            [context addIdentificationEntryWithNextSequentialPhoneNumberCXCallDirectoryPhoneNumber)[phoneNumber unsignedLongLongValue] label:label];
        }
        
        [context completeRequestWithCompletionHandler:nil];
    }

3、关键问题

app内通讯录数据都是从接口获取的,app第一次启动的时候肯定是没有的。文档上说,上面的方法只在系统启动app扩展的时候调用一次,我们必须在调用的时候就把认证信息都传进去,也就是说想通过接口取网络数据更新认证名单是没戏了。

demo中,点击get Contact Data按钮会利用NSUserDefaults存储一个简单的数据来模拟获取的通讯录数据,然后在beginRequestWithExtensionContext中进行读取。数据的传递利用app group。

屏幕快照 2016-10-13 上午11.10.04
4、总结

感觉并没有达到我的预期效果,主要问题

    无法更新认证名单
    系统通讯录如果存在这个号码,基本就没作用了。
    卸载了app,通话记录还会存在认证信息。

iOS的权限开放程度和几年前比真是相差万别,现在系统也越来越花哨,总有一种感觉是为了迎合中国用户的需求。我还是喜欢简洁实用的系统。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0