iOS CallKit初體驗

概述

該CallKit框架提供VoIP功能,以及呼叫限制和識別的編程訪問。

VoIP功能

應用程序可以使用CallKit接聽來電欢摄,并使用本地電話用戶界面呼出。

接收來電

要接收來電笋粟,一個應用程序創(chuàng)建一個CXProvider對象怀挠,并將其存儲在全局訪問。一個應用程序報告給provider一個來電以響應外部通知害捕,如VoIP的推送通知绿淋。

這部分內(nèi)容看起來不太容易理解,最好下載官方提供的源碼尝盼,最好再看一看官方視頻吞滞。
另外,源碼只有Swift版沒有OC版盾沫。
源碼下載地址

注意

有關VoIP的推送通知和PushKit的更多信息裁赠,請參閱IP語音(VoIP)的最佳實踐。

使用由外部通知中提供的信息赴精,應用程序創(chuàng)建的UUID和CXCallUpdate對象唯一標識呼叫佩捞,主叫方,并把它們傳遞給使用 reportNewIncomingCallWithUUID:update:completion:方法蕾哟。

一旦電話接通后一忱,供應商代表發(fā)送provider:performStartCallAction:在實現(xiàn)中,delegate 負責配置AVAudioSession并且當操作完成的時候會調(diào)fulfill方法谭确。

同樣的帘营,這段文字的說明也最好配合源碼來解讀。

外呼

用戶可以以以下任何一個方式中在VoIP應用中發(fā)起外呼:

  • 執(zhí)行應用程序內(nèi)的交互
  • 打開支持自定義URL方案的鏈接
  • 啟動Siri的使用VoIP通話

要撥出電話琼富,一個應用程序從CXCallController對象請求CXStartCallAction仪吧。的動作是由一個UUID來唯一標識呼叫和CXHandle對象來指定收件人。

呼叫限制 & 驗證

應用程序可以創(chuàng)建一個呼叫目錄擴展鞠眉,根據(jù)手機號碼去驗證或限制來電薯鼠。

注意

在電話號碼簿電話分機號碼由CXCallDirectoryPhoneNumber類型代表择诈,包括后面的數(shù)字序列的國碼(如1北美或86中國)。

如何創(chuàng)建Call Directory Extension?

所有創(chuàng)建Extension的方式都是一樣的出皇,詳見我的另一篇文章羞芍。
iOS Action Extension開發(fā)教程,實現(xiàn)跨APP的數(shù)據(jù)共享

使用

所有的來電驗證和限制都在beginRequestWithExtensionContext:方法的實現(xiàn)中郊艘。
beginRequestWithExtensionContext方法在CallDirectoryHandler類中荷科,其實CallDirectoryHandlerCXCallDirectoryProvider的子類,在你創(chuàng)建完Call Directory Extension后纱注,在擴展文件中可以看到系統(tǒng)生成的文件畏浆,在這個文件中就可以看到該方法。

識別來電者

當一個手機接收來電時狞贱,系統(tǒng)會在第一時間參考用戶的聯(lián)系人目錄去尋找匹配的手機號碼刻获。如果沒有匹配的,系統(tǒng)會到你應用程序的Call Directory Extension中去尋找匹配的手機號碼瞎嬉,這有益于保持用戶的聯(lián)系人信息和系統(tǒng)的聯(lián)系人信息相對獨立蝎毡,比如一個社交網(wǎng)絡,或者驗證由應用程序發(fā)起的來電氧枣,比如客戶服務支持或交付通知沐兵。

舉個例子,考慮某個用戶誰是Jane的社交網(wǎng)絡app的好友便监,但是Jane的聯(lián)系人中沒有這個人手機號碼扎谎。于是這個社交網(wǎng)絡APP可以使用Call Directory Extension,下載并添加所有該用戶朋友的手機號碼烧董。正因為如此簿透,當該用戶接受到一個來自于Jane的來電時,系統(tǒng)會顯示一些像"(App Name) Caller ID: Jane Applesedd"而不是像"Unknown Caller"解藻。

若要提供有關來電者身份信息,你可以在beginRequestWithExtensionContext:的方法實現(xiàn)中使用addIdentificationEntryWithNextSequentialPhoneNumber:label:方法葡盗。

代碼如下:

@interface CallDirectoryHandler () <CXCallDirectoryExtensionContextDelegate>
@end

@implementation CallDirectoryHandler

//識別和攔截通過該方法設置
- (void)beginRequestWithExtensionContext:(CXCallDirectoryExtensionContext *)context {
    context.delegate = self;

    if (![self addBlockingPhoneNumbersToContext:context]) {
        NSLog(@"Unable to add blocking phone numbers");
        NSError *error = [NSError errorWithDomain:@"CallDirectoryHandler" code:1 userInfo:nil];
        [context cancelRequestWithError:error];
        return;
    }
    
    if (![self addIdentificationPhoneNumbersToContext:context]) {
        NSLog(@"Unable to add identification phone numbers");
        NSError *error = [NSError errorWithDomain:@"CallDirectoryHandler" code:2 userInfo:nil];
        [context cancelRequestWithError:error];
        return;
    }
    
    [context completeRequestWithCompletionHandler:nil];
}

//來電驗證身份
- (BOOL)addIdentificationPhoneNumbersToContext:(CXCallDirectoryExtensionContext *)context {
    // Retrieve phone numbers to identify and their identification labels from data store. For optimal performance and memory usage when there are many phone numbers,
    // consider only loading a subset of numbers at a given time and using autorelease pool(s) to release objects allocated during each batch of numbers which are loaded.
    //
    // Numbers must be provided in numerically ascending order.
    CXCallDirectoryPhoneNumber phoneNumbers[] = { 18775555555, 18885555555 };
    NSArray<NSString *> *labels = @[ @"Telemarketer", @"Local business" ];
    NSUInteger count = (sizeof(phoneNumbers) / sizeof(CXCallDirectoryPhoneNumber));

    for (NSUInteger i = 0; i < count; i += 1) {
        CXCallDirectoryPhoneNumber phoneNumber = phoneNumbers[i];
        NSString *label = labels[i];
        //這里可以檢查來電者的身份信息
        [context addIdentificationEntryWithNextSequentialPhoneNumber:phoneNumber label:label];
    }

    return YES;
}
@end

beginRequestWithExtensionContext:這個方法只有當系統(tǒng)啟動App Extension時才會被調(diào)用螟左,而不是每次單獨來電時調(diào)用,你必須一次性指定全部的“呼叫標識信息”觅够。

阻止來電

當一個手機接收到來電時胶背,系統(tǒng)首先會參考用戶的黑名單以確定哪個呼叫時應該被阻止。如果這個手機號碼不在用戶或者系統(tǒng)定義的黑名單中喘先,系統(tǒng)就會參考應用程序的Call Direcotry Extension去尋找匹配的黑名單號碼钳吟。這樣做有益于應用程序,允許用戶依據(jù)一套準則阻止任意的號碼窘拯。

去阻止特定手機號碼的來電红且,你你可以在beginRequestWithExtensionContext:的方法實現(xiàn)中使用addBlockingEntryWithNextSequentialPhoneNumber::方法坝茎。

代碼如下:

@interface CallDirectoryHandler () <CXCallDirectoryExtensionContextDelegate>
@end

@implementation CallDirectoryHandler

//識別和攔截通過該方法設置
- (void)beginRequestWithExtensionContext:(CXCallDirectoryExtensionContext *)context {
    context.delegate = self;

    if (![self addBlockingPhoneNumbersToContext:context]) {
        NSLog(@"Unable to add blocking phone numbers");
        NSError *error = [NSError errorWithDomain:@"CallDirectoryHandler" code:1 userInfo:nil];
        [context cancelRequestWithError:error];
        return;
    }
    
    if (![self addIdentificationPhoneNumbersToContext:context]) {
        NSLog(@"Unable to add identification phone numbers");
        NSError *error = [NSError errorWithDomain:@"CallDirectoryHandler" code:2 userInfo:nil];
        [context cancelRequestWithError:error];
        return;
    }
    
    [context completeRequestWithCompletionHandler:nil];
}

//來電攔截
- (BOOL)addBlockingPhoneNumbersToContext:(CXCallDirectoryExtensionContext *)context {
    // Retrieve phone numbers to block from data store. For optimal performance and memory usage when there are many phone numbers,
    // consider only loading a subset of numbers at a given time and using autorelease pool(s) to release objects allocated during each batch of numbers which are loaded.
    //
    // Numbers must be provided in numerically ascending order.
    CXCallDirectoryPhoneNumber phoneNumbers[] = { 14085555555, 18005555555 };
    NSUInteger count = (sizeof(phoneNumbers) / sizeof(CXCallDirectoryPhoneNumber));

    for (NSUInteger index = 0; index < count; index += 1) {
        CXCallDirectoryPhoneNumber phoneNumber = phoneNumbers[index];
        [context addBlockingEntryWithNextSequentialPhoneNumber:phoneNumber];
    }

    return YES;
}
@end

總結

如果項目不使用VoIP,看 呼叫限制 & 驗證 模塊之后的內(nèi)容就可以了暇番。然后在擴展類的相應方法中配置各自的名單嗤放。
如果項目中使用VoIP,請繼續(xù)看其他資料壁酬。

其他資料詳見

本文翻譯自Call Directory Extension Apple官方文檔
Enhancing VoIP Apps with CallKit

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末次酌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子舆乔,更是在濱河造成了極大的恐慌岳服,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件希俩,死亡現(xiàn)場離奇詭異吊宋,居然都是意外死亡,警方通過查閱死者的電腦和手機斜纪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門贫母,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盒刚,你說我怎么就攤上這事腺劣。” “怎么了因块?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵橘原,是天一觀的道長。 經(jīng)常有香客問我涡上,道長趾断,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任吩愧,我火速辦了婚禮芋酌,結果婚禮上,老公的妹妹穿的比我還像新娘雁佳。我一直安慰自己脐帝,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布糖权。 她就那樣靜靜地躺著堵腹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪星澳。 梳的紋絲不亂的頭發(fā)上疚顷,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音,去河邊找鬼腿堤。 笑死阀坏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的释液。 我是一名探鬼主播全释,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼误债!你這毒婦竟也來了浸船?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤寝蹈,失蹤者是張志新(化名)和其女友劉穎李命,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箫老,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡封字,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了耍鬓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阔籽。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖牲蜀,靈堂內(nèi)的尸體忽然破棺而出笆制,到底是詐尸還是另有隱情,我是刑警寧澤涣达,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布在辆,位于F島的核電站,受9級特大地震影響度苔,放射性物質(zhì)發(fā)生泄漏匆篓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一寇窑、第九天 我趴在偏房一處隱蔽的房頂上張望鸦概。 院中可真熱鬧,春花似錦甩骏、人聲如沸完残。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至熟掂,卻和暖如春缎浇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赴肚。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工素跺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留二蓝,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓指厌,卻偏偏與公主長得像刊愚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子踩验,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

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

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理鸥诽,服務發(fā)現(xiàn),斷路器箕憾,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 新特性 對于開發(fā)者來說牡借,好消息是 iOS 10 中并沒有加入太多內(nèi)容。按照適配的需求袭异,來年的 iOS 開發(fā)至少應該...
    9d710097e616閱讀 769評論 0 1
  • WWDC2106 iOS10新特性及開發(fā)者要注意什么 當晚看了WWDC2016直播钠龙,第二天我安裝了iOS10試用版...
    五八四十閱讀 2,057評論 0 1
  • 關于鄭州我想的全是你,想來想去都是懺悔和委屈御铃;關于鄭州我愛的全是你碴里,愛來愛去不明白愛的意義。關于鄭州鄭州只是偶爾想...
    周小粥粥閱讀 663評論 8 7
  • 主持人: 大家很不容易走過90天上真。 畢業(yè)總結會議結束后咬腋,大群就會解散了,要移到大群的同學會谷羞,還沒有進群的同學找雅文...
    小溪01號家庭陪伴師閱讀 297評論 0 0