利用callKit实现电话防骚扰

callKit框架是ios10之后更新的一个框架,代替了原来的CoreTelephony.framework,使用CallKit可以实现电话的拦截

首先创建一个项目之后,创建一个target,选择Call Directory Extension,会创建一个extension

限制通话的三个方法已经实现但是需要修改,还要在主程序里面添加检测授权的方法和更新电话的代码

一、主程序的代码

检测是否授权,如果想要拦截某个电话,需要在设置界面,设置->电话->来电阻止与身份识别内打开授权,如果用户没有授权需要检测是否授权,可以每隔一段时间检测一下,如果没有授权就提醒一下。

注意ExtensionWithIdentifier这个参数是extension的bundle Identifier
-(void)checkPermissions
{
    CXCallDirectoryManager *manager = [CXCallDirectoryManager sharedInstance];
    // 获取权限状态
    [manager getEnabledStatusForExtensionWithIdentifier:@"XXXXXX" completionHandler:^(CXCallDirectoryEnabledStatus enabledStatus, NSError * _Nullable error) {
        if (!error) {
            NSString *title = nil;
            if (enabledStatus == CXCallDirectoryEnabledStatusDisabled ) {
                title = @"未授权,请在设置->电话->来电阻止与身份识别内授权相关权限";
 
            }
        }
    }];
}

 

给主程序添加代码,array是一个数组,里面存放着电话号码,利用NSUserDefaults把数组存放在app group,group的标识要和这里的一致

注意:另外需要注意的是数组必须是升序的,且必须以86开头的
注意:创建NSUserDefaults的时候有个参数是initWithSuiteName:这里要和后面的名称一致
 NSUserDefaults * userDefaults = [[NSUserDefaults alloc]initWithSuiteName:@“XXXXXXXX"];
    NSArray *sortedArray = [self.mPhoneNumberList sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        return [obj1 compare:obj2];
    }];
    [userDefaults setObject:sortedArray forKey:@"blackPhoneNum"];
    [userDefaults synchronize];
    [self checkPermissions];
    [self updateData];

 

更新需要拦截的电话

-(void)updateData
{
    CXCallDirectoryManager *manager = [CXCallDirectoryManager sharedInstance];
    [manager reloadExtensionWithIdentifier:@“XXXXXXX" completionHandler:^(NSError * _Nullable error) {
    }];

}

 

二.extensiond的代码CallDirectoryHandler.m的方法实现

 

- (BOOL)addBlockingPhoneNumbersToContext:(CXCallDirectoryExtensionContext *)context {
    NSUserDefaults * userDefaults = [[NSUserDefaults alloc]initWithSuiteName:@“XXXXXXXX"];
      NSArray * array =  [userDefaults objectForKey:@"blackPhoneNum"];
    [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString * phoneStr  = obj;
        int64_t phoneInt = [phoneStr integerValue];
        CXCallDirectoryPhoneNumber  number = phoneInt ;
         [context addBlockingEntryWithNextSequentialPhoneNumber:number];
    }];
    return YES;
}

- (BOOL)addIdentificationPhoneNumbersToContext:(CXCallDirectoryExtensionContext *)context {
    NSUserDefaults * userDefaults = [[NSUserDefaults alloc]initWithSuiteName:@“XXXXXX"];
    NSArray * array =  [userDefaults objectForKey:@"blackPhoneNum"];
    [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString * phoneStr  = obj;
        int64_t phoneInt = [phoneStr integerValue];
        CXCallDirectoryPhoneNumber  number = phoneInt ;
        NSString *label = @"黑名单";
        [context addIdentificationEntryWithNextSequentialPhoneNumber:number label:label];
    }];
    return YES;
}

 

三.extension和程序之间是不能通讯的,需要利用app group来共享内存,

打开app group的方法,注意需要在主项目和extension都打开并选择同一个标识

TARGETS-->AppExtensionDemo-->Capabilities-->App Groups

posted @ 2017-04-18 17:47  一米王子  阅读(1747)  评论(0编辑  收藏  举报