推荐序
本文介绍了 iOS 10 中的 Call Directory Extension 特性,并且最终 Demo 出一个来电黑名单的 App。
阅读须知:目前学习的资料也仅限相关 API,另外 API 也没有详细的注释,所以本文主要是个人探索所得,如果有什么错误,还望见谅并予以指正。现在,让我们开始吧~
API 介绍
Extension 一直给我的印象就是很轻量,单一的,就如之前接触的 Photo Editing Extension 一样,使用起来十分简单。这次的 Call Directory Extension 也不出例外,出奇的简单。只涉及了两个类,四个方法。下面我们逐一介绍:
//// CXCallDirectoryProvider.h// CallKit@available(iOS 10.0, *)
public class CXCallDirectoryProvider : NSObject, NSExtensionRequestHandling {
public func beginRequest(with context: CXCallDirectoryExtensionContext)}
Now, Go on~
接下来是另外一个类 CXCallDirectoryExtensionContext,它提供了另外三个方法,如下所示:
//// CXCallDirectoryExtensionContext.h// CallKit@available(iOS 10.0, *)
public class CXCallDirectoryExtensionContext : NSExtensionContext {
public func addBlockingEntry(withNextSequentialPhoneNumber phoneNumber: String)
public func addIdentificationEntry(withNextSequentialPhoneNumber phoneNumber: String, label: String)
public func completeRequest(completionHandler completion: ((Bool) -> Swift.Void)? = nil)}
实战演示
虽然自认为上面的描述已经够详细了,不过这里还是有必要详细走一遍流程,以免遗漏。
开发环境:Xcode8.0 Beta 64 位 iOS10 设备(至于为什么 64 位,之后再解释,说多了都是泪 ..)
1. 创建工程
没什么特别。 Xcode —> File —> New —> Project。随便选个 iOS Application,创建即可。这里我选择开发语言为 Swift,你随意~。
这里我们的目标是来电黑名单,也就是 Extension 部分,所以创建好的 Containing App,不用做什么改动。
2. 添加 Extension
Xcode —> File —> New —> Target。创建一个 Call Directory Extension,如下图所示:
这里注意下底部的说明, (This extension and the app it is bundled with must be 64-bit only)也就是,这个 extension 只支持 64 位的设备,坑爹有没有!!之前创建太急,没认真看,用那台 5C 倒腾了半天,就是出问题。只好狠心把主力机也升级了。
创建好 Extension,会弹出这样的提示框:
询问我们是否激活这个 scheme,当然选择激活咯,继续~
这里的相关代码如下:
import Foundation
import CallKit
class CallDirectoryHandler: CXCallDirectoryProvider {
override func beginRequest(with context: CXCallDirectoryExtensionContext) {
// — 1
guard let phoneNumbersToBlock = retrievePhoneNumbersToBlock() else {
NSLog("Unable to retrieve phone numbers to block")
let error = NSError(domain: "CallDirectoryHandler", code: 1, userInfo: nil)
context.cancelRequest(withError: error)
return
}
// — 2
for phoneNumber in phoneNumbersToBlock {
context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
}
// — 3
guard let (phoneNumbersToIdentify, phoneNumberIdentificationLabels) = retrievePhoneNumbersToIdentifyAndLabels() else {
NSLog("Unable to retrieve phone numbers to identify and their labels")
let error = NSError(domain: "CallDirectoryHandler", code: 2, userInfo: nil)
context.cancelRequest(withError: error)
return
}
// — 4
for (phoneNumber, label) in zip(phoneNumbersToIdentify, phoneNumberIdentificationLabels) {
context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)
}
// — 5
context.completeRequest()
}
private func retrievePhoneNumbersToBlock() -> [String]? {
// retrieve list of phone numbers to block
return [" 8618xxxx157"]
}
private func retrievePhoneNumbersToIdentifyAndLabels() -> (phoneNumbers: [String], labels: [String])? {
// retrieve list of phone numbers to identify, and their labels
return ([" 8618xxxx569"], [" 测试 "])
}
}
一个简单的来电黑名单,我们只要补全 retrievePhoneNumbersToBlock 和 retrievePhoneNumbersToIdentifyAndLabels 中的相关数据即可,它们分别表示直接加入黑名单的号码以及识别出来,需要判断的号码。
现在我们具体看一下这个类到底做了什么。
在 // —- 1 中,先判断是否成功调用了 retrievePhoneNumbersToBlock 方法,如果没有,则打印 Log: Unable to retrieve phone numbers to block,然后直接终止这次请求并返回。
在 // —- 2 中,遍历添加黑名单中的号码,这里的号码将直接拦截。
在 // —- 3 中,先判断是否成功调用了 retrievePhoneNumbersToIdentifyAndLabels 方法,如果没有,则打印 Log: Unable to retrieve phone numbers to identify and their labels,然后直接终止这次请求并返回。
在 // —- 4 中,遍历添加识别后的号码及其描述,这里的号码将连带描述一起显示。
在 // —- 5 中,完成提交请求。
到这里,代码已经全部完成了。
3. 开启权限
至此,相关的工作就都完成了,我们的来电黑名单也已经实现了,可以用添加到列表中的号码来测试啦,如下所示:
相关思考及后续
当然,对于 CallKit 的学习,我也仅限于这一两天,还是没有资料的情况下。所以文中难免存在各种错误以及遗漏,欢迎指正。
这之后,继续 CallKit 的学习,实现它的另外一个功能:VoIP App。 wait…
Enjoy it~
参考链接
Enhancing VoIP Apps with CallKit:https://developer.apple.com/videos/play/wwdc2016/230/
CallKit: https://developer.apple.com/reference/callkit
全文完,本文的所有打赏归余龙泽所有。
赞助商: