iOS10 CallKit 之来电识别功能

先导入 Call Directory Extension

iOS10 CallKit 之来电识别功能_第1张图片

导入完成后,项目会多了一个文件夹
文件夹里的文件是CallKit 中 来电识别功能 添加黑名单功能的实现模版

iOS10 CallKit 之来电识别功能_第2张图片

发现问题:
1,addBlockingPhoneNumbersToContextaddIdentificationPhoneNumbersToContext,这两个方法中 承载电话号的 数据类型是CXCallDirectoryPhoneNumber , 这个类型是int64_t类型,也是long long类型,所以大家在做类型转换的时候需要注意。

2,如何动态修改CXCallDirectoryPhoneNumber数组和对应的标识数组?

iOS10 CallKit 之来电识别功能_第3张图片

因为宿主程序 和 扩展程序的数据 是隔离的,所以我们需要在宿主程序和 扩展程序都 开启 APP Groups

iOS10 CallKit 之来电识别功能_第4张图片
iOS10 CallKit 之来电识别功能_第5张图片

宿主程序和 扩展程序都设置完 APP Groups 就可以共享数据了。
在宿主程序中把从服务端请求回来的最新数据,写入到NSUserDefaults 中,我用来电识别功能举个 ,如下:

NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.testCallKit"];
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:10];
    [dict setObject:@"欧弟122" forKey:@"8615657138888"];
    [userDefault setObject:dict forKey:@"PhoneNumbers"];
    [userDefault synchronize];

上面代码 需要注意的是 :
1, SuiteName的名字 是刚才设置 APP Groups 时创建的。
2,电话号码前面要加 区号 ,中国大陆的区号就是 86 或者 +86。

回到 CallDirectoryHandler.m 更改如下:

- (BOOL)addIdentificationPhoneNumbersToContext:(CXCallDirectoryExtensionContext *)context {
    NSDictionary *dict = [[[NSUserDefaults alloc] initWithSuiteName:@"group.testCallKit"] objectForKey:@"PhoneNumbers"];
    NSMutableDictionary *incomingTelegramInfo  = @{}.mutableCopy;
    
    [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        incomingTelegramInfo[@([key longLongValue])] = obj;
    }];
    
    for (NSNumber *phoneNumber in [incomingTelegramInfo.allKeys sortedArrayUsingSelector:@selector(compare:)]) {
        NSString *label = incomingTelegramInfo[phoneNumber];
        [context addIdentificationEntryWithNextSequentialPhoneNumber:(CXCallDirectoryPhoneNumber)[phoneNumber unsignedLongLongValue] label:label];
    }
    return YES;
}
iOS10 CallKit 之来电识别功能_第6张图片
测试结果

那么如何维护号码库呢?
经调研发现,目前非越狱手机没有 获取来电号码 的权限,所以就不能用 单个来电号码 去云端数据库比对处理,只能通过第三方应用 把号码数据库写入到手机本地,当来电时 系统自动去和本地号码库比对 并做出身份显示。
机制如下:

iOS10 CallKit 之来电识别功能_第7张图片

我也咨询了做安卓的童鞋,如何在来电时触发第三方应用,他提供了 保活进程 的思路。我这里就不过多阐述了。可以参考 Android来电号码获取代码

iOS 参考:
官方文档
iOS关于系统电话、短信的调用

你可能感兴趣的:(iOS10 CallKit 之来电识别功能)