iOS CallKit來電識(shí)別和號(hào)碼拉黑

前言

最近兩天公司有需求研究CallKit來電識(shí)別和號(hào)碼拉黑姆坚,在網(wǎng)上找了一些相關(guān)博文拌倍。但是發(fā)現(xiàn)對(duì)于沒接觸過這方面的人來說勋又,還是會(huì)遇到一些問題,所以打算自己再寫一篇詳盡的文章八拱。
懶得看的請(qǐng)直接下載最下面demo。

細(xì)節(jié)

在沒有了解CallKit這兩個(gè)功能之前涯塔,因?yàn)橄旅娴膬?nèi)容肌稻,導(dǎo)致產(chǎn)生一些失(cao)敗(dan)的嘗試。包括但不限于以下:

  • 如果該號(hào)碼已存在手機(jī)里匕荸,標(biāo)記識(shí)別將會(huì)無效
  • 如果屏蔽某號(hào)碼爹谭,看不到該號(hào)碼來電
  • 打開主App和擴(kuò)展App的數(shù)據(jù)共享,以實(shí)現(xiàn)兩個(gè)應(yīng)用共享數(shù)據(jù)
  • 添加到call表單中的電話號(hào)碼必須帶上國家區(qū)號(hào)
  • 添加號(hào)碼到表單之前榛搔,需要對(duì)數(shù)據(jù)進(jìn)行去重和升序排列
  • 最大數(shù)量在100萬到200萬之間诺凡,原因可能是超時(shí)無效
  • 目前好像只能全量更新數(shù)據(jù),不能增量更新践惑,效率比較低

過程

1. 首先腹泌,建立一個(gè)工程或者在原有工程上,加入擴(kuò)展應(yīng)用 Call Directory Extension:

  • 選擇new->target->Call Directory Extension
選擇new->target->Call Directory Extension
  • 在這個(gè)文件中尔觉,蘋果默認(rèn)已經(jīng)寫好了注入事件的代碼凉袱,并默認(rèn)添加了兩個(gè)手機(jī)號(hào)供參考格式。


    CallDirectoryHandle.m
  • 正是因?yàn)檫@倆默認(rèn)號(hào)碼的格式侦铜,容易產(chǎn)生誤導(dǎo)专甩,如果按照這個(gè)格式來寫,不帶國家區(qū)號(hào)的話钉稍,號(hào)碼是無法添加到 CXCallDirectoryExtensionContext 里面的涤躲,也就是會(huì)添加失敗,導(dǎo)致產(chǎn)生了一種“這不可能”的心態(tài)贡未。

1B5104F2-0BEB-40B9-BB09-30E3CB814253.png
  • 在做這里的時(shí)候种樱,我想當(dāng)然的認(rèn)為,它只是一個(gè)本地沙盒或者數(shù)據(jù)庫類型的介質(zhì)羞秤,也就是任何形式的字符數(shù)據(jù)都可以存儲(chǔ)進(jìn)去(CXCallDirectoryPhoneNumber是int64_t)缸托,實(shí)際上,它在存儲(chǔ)前進(jìn)行了數(shù)據(jù)格式判斷瘾蛋,不帶 #國家區(qū)號(hào)# 的數(shù)據(jù)是無法存儲(chǔ)成功的俐镐,直接失敗并導(dǎo)致權(quán)限丟失。

權(quán)限打開方式:設(shè)置->電話->來電阻止與身份識(shí)別

  • 我嘗試了一下是否可以用openUrl方式哺哼,直接讓應(yīng)用跳轉(zhuǎn)到來電身份權(quán)限頁面佩抹。遺憾的是失敗了叼风,可能是沒有開放這個(gè)接口,或者我沒找到棍苹。第一行跳轉(zhuǎn)到電話設(shè)置頁面有效无宿。

Phone — prefs:root=Phone
Phone — prefs:root=Phone&CALL_BLOCKING&IDENTIFICATION

2. 接著,進(jìn)行Main App和Extension App之間數(shù)據(jù)通訊枢里。

  • 測試功能時(shí)孽鸡,直接在擴(kuò)展應(yīng)用 Call Directory Extension 中寫入了自己的號(hào)碼嘗試成功。不過栏豺,擴(kuò)展APP和主APP雖然在同一個(gè)工程里彬碱,但是是兩個(gè)應(yīng)用,傳遞數(shù)據(jù)的話需要用到數(shù)據(jù)共享:App Group.
共享數(shù)據(jù).png
  • App共享數(shù)據(jù)的方法有兩種奥洼,至于寫入數(shù)據(jù)的方式巷疼,可以采用數(shù)組、字典或者數(shù)據(jù)庫灵奖。
  1. 使用共享url地址嚼沿,寫入文件
    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.RexLocalGroup"];
  1. 使用本地沙盒,寫入沙盒中
    NSUserDefaults *myDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.RexLocalGroup"];
  • 簡書上有人采用 fgets(char *buf, int bufsize, FILE *stream) 函數(shù)讀行的形式來解析數(shù)據(jù)瓷患,我試了一下骡尽,可以實(shí)現(xiàn)存入100萬條數(shù)據(jù),但200萬的時(shí)候會(huì)異常尉尾,應(yīng)該是蘋果做了一些限制爆阶。不過這種方式,只適合從服務(wù)器拉取數(shù)據(jù)文件寫入沙咏,如果想在移動(dòng)端去添加數(shù)據(jù)到文件里辨图,就會(huì)非邏輯化。所以如果想實(shí)現(xiàn)移動(dòng)端主動(dòng)寫入的話肢藐,用數(shù)據(jù)庫會(huì)容易操作一些故河。
    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.RexLocalGroup"];
    containerURL = [containerURL URLByAppendingPathComponent:@"Library/"];
    NSString * dbPath = [NSString stringWithFormat:@"%@%@",containerURL.absoluteString, @"LocalNumberDB.sqlite"];
    _dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
  • 主應(yīng)用中把數(shù)據(jù)庫建立到這個(gè)數(shù)據(jù)共享URL位置,然后吆豹,在擴(kuò)展應(yīng)用中提取數(shù)據(jù)并填入CXCallDirectoryExtensionContext表單中鱼的。這樣就實(shí)現(xiàn)了數(shù)據(jù)傳遞。比較遺憾的是目前只能是全量更新號(hào)碼庫痘煤,無法實(shí)現(xiàn)增量更新凑阶,所以更新一條數(shù)據(jù)也需要全部重新存一遍,速度比較慢衷快,可能這也是種隱私保護(hù)宙橱。
    NSArray * contacts = [[FMDataBaseManager shareInstance] getAllContacts:kNumberTable];
    for (int i= 0; i < contacts.count; i ++) {
        @autoreleasepool {
            ContactModel * contact = contacts[i];
            if (contact.phoneNumber && contact.identification) {
                CXCallDirectoryPhoneNumber phoneNumber = [contact.phoneNumber longLongValue];
                NSString * label = contact.identification;
                [context addIdentificationEntryWithNextSequentialPhoneNumber:phoneNumber label:label];
            }
            contact = nil;
        }
    }
  • 簡單幾步,即可感覺到這個(gè)強(qiáng)(mei)大(luan)的(yong)功能的作用。
    有疑問可以留言

參考項(xiàng)目下載

做了一個(gè)完整的demo放在了GitHub上师郑,有興趣可以下載环葵。

[link]https://github.com/Rex-xingjl/CallKitDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宝冕,隨后出現(xiàn)的幾起案子张遭,更是在濱河造成了極大的恐慌,老刑警劉巖地梨,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菊卷,死亡現(xiàn)場離奇詭異,居然都是意外死亡宝剖,警方通過查閱死者的電腦和手機(jī)的烁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诈闺,“玉大人,你說我怎么就攤上這事铃芦⊙拍鳎” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵刃滓,是天一觀的道長仁烹。 經(jīng)常有香客問我,道長咧虎,這世上最難降的妖魔是什么卓缰? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮砰诵,結(jié)果婚禮上征唬,老公的妹妹穿的比我還像新娘。我一直安慰自己茁彭,他們只是感情好总寒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著理肺,像睡著了一般摄闸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妹萨,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天年枕,我揣著相機(jī)與錄音,去河邊找鬼乎完。 笑死熏兄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霍弹,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼毫别,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了典格?” 一聲冷哼從身側(cè)響起岛宦,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耍缴,沒想到半個(gè)月后砾肺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡防嗡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年变汪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚁趁。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裙盾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出他嫡,到底是詐尸還是另有隱情番官,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布钢属,位于F島的核電站徘熔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏淆党。R本人自食惡果不足惜酷师,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望染乌。 院中可真熱鬧山孔,春花似錦、人聲如沸慕匠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽台谊。三九已至蓉媳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锅铅,已是汗流浹背酪呻。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盐须,地道東北人玩荠。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阶冈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子闷尿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容