利用CallKit 实现来电识别 遇到的一些坑

最近项目中新增了一个需求,需要使用 iOS 10 中新增的 CallKit 来实现一个来电识别的功能。按照惯例,先在网上搜索了一下,看了几篇文章,觉得实现起来很简单嘛。于是就愉快的开始了,然后就开始遇见一个个坑,网上目前存在的文章都是简单的实现了号码识别,但是关于号码规则、大数量的数据如何处理等都没有提及。这篇文字就记录下我个人在实现这个功能时遇到的坑以及如何解决的。

一,具体实现

如何实现就不在详细描写了,网上已经有很多的文章写了。

二,具体功能实现遇到的各种坑

号码规则
  1. 号码必须进行排列,添加顺序为优先添加小的号码。譬如:123和132两个号码要先添加123,然后添加132.
  2. 号码的格式化,手机号码前面需要添加国家码,固话需要带有区号,然后区号去零,然后前面添加国家码。譬如手机号:185XXXXX8497 需要格式化为86185XXXXX8497;固话 0755-12345678 需要格式化为:8675512345678.
  3. 号码去重,一个手机号码只能添加一次,添加多次会开启失败。
    PS:大文件的号码排序、去重可以看看我的另一篇文章:大文件内容使用shell 排序、去重
大数量的数据如何添加

大数据不能一下读取到内存中,否则会导致打开失败。我们给的号码库有三十几M,大概100万数据,刚开始直接读入内存中,一直打开失败。解决办法:从文件中一行行读取数据,使用后释放。我的号码库文件,大概这样的形式:

[
{"86196852102": "骚扰电话"},
{"86196852201": "诈骗电话"},
{"86196852202": "骚扰电话"},
{"86196852213": "诈骗电话"},
{"86201008613": "广告推销"},
{"86202096585": "诈骗电话"},
{"86211008611": "广告推销"},
{"86216618834": "广告推销"},
{"86219506524": "骚扰电话"},
]

具体代码如下:

 NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:groupIdentifierExtension];
   //文件路径
   containerURL = [containerURL URLByAppendingPathComponent:LocalstorageName];
   NSString* fileRoot = containerURL.path;
   FILE *file = fopen([fileRoot UTF8String], "r");
   char buffer[1024];
   while (fgets(buffer, 1024, file) != NULL){
       @autoreleasepool {
           NSString* result = [NSString stringWithUTF8String:buffer];
           result = [result stringByReplacingOccurrencesOfString:@"," withString:@""];
           NSData *jsonData = [result dataUsingEncoding:NSUTF8StringEncoding];
           NSError *err;
           NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                               options:NSJSONReadingAllowFragments
                                                                 error:&err];
           if(err)
           {
           }else
           {
               NSString *number = dic.allKeys[0];
               NSString *name = dic[number];
               
               if (number == nil || name == nil)
               {
               }else {
//                    number = [self fixPhone:number];
                   CXCallDirectoryPhoneNumber phoneNumber = [number longLongValue];
                   [context addIdentificationEntryWithNextSequentialPhoneNumber:phoneNumber label:name];
               }

           }
           dic = nil;
       }
       
   }

实际测试,将近100万的数据在 6S Plus 15S内可以完成加载。

号码库更新后如何通知系统更新数据

号码库可以通过下载进行更新,一般下载的是压缩包,解压缩后,把数据写进共享文件内,更新数据后,需要通知系统去刷新数据库,是数据生效。具体解压缩可以搜索: SSZipArchive ,扩展和主APP数据扩展可以看这篇文章:WWDC2014之App Extensions学习笔记 通知系统刷新号码数据库的具体代码:

//IdentifierExtension 为扩展的 Bundle Identifier
 CXCallDirectoryManager *manager = [CXCallDirectoryManager sharedInstance];
  [manager reloadExtensionWithIdentifier:IdentifierExtension completionHandler:^(NSError * _Nullable error) {
  }];
要使用真机调试

不要使用模拟器,用模拟器调试时的错误不要管。血的教训,查看用户扩展的使用权限和更新数据时使用模拟器一直报错,找了半天的错误,换了真机就没有问题,也是我自己2了 [二哈] 。

数据可以分开写

这句话的意思是先写入少量的数据,让用户打开权限时,感觉不到延时,当权限打开后,在写入大量的数据,刷新数据源,用户感觉不到等待的时间。

因为之前说了写入几十万的 数据需要大概十几秒的时间,在我的思维里面觉得是很正常的,但是在产品眼里这是不可接受的。巴拉巴拉说了一堆,说腾讯啊、360啊人家都打开的很快的。你娘啊!!好吧算你赢。
最后想到一个办法,先写入很少量的数据,然后在写入大量的数据。这样就完美的解决了第一次加载时间慢的问题。
具体的来说就是,第一次请求用户打开权限的时间,先写入很少量的数据,当判断用户已经打开了权限,就写入大量的数据,然后刷新下数据源,这样就是在用户完全没有感知的情况下刷新了数据源。

最好提供一个演示视频

审核的苹果爸爸使用的 iPad 测试,然后把我们拒了,说不知道如何使用 CallKit

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,512评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,029评论 4 62
  • 小孩教育,你舍得严厉吗?董事长杜总分享了他自己看法。 我女儿今年考上大学,过年时,我把她拉过来好好谈了一次话。 “...
    河马先森阅读 227评论 2 0
  • 在编辑标题前,其实早就想好了一个标题:被出版社的编辑找到约插画是什么感觉?倒也不是因为这个标题会吸引多些眼球,实在...
    夏暖心阅读 503评论 9 8