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