iOS反骚扰电话-CallKit

简介:

iOS10增加了识别骚扰电话的API,有三款主流的软件已经实现。也有一些报道分析 前几天查了查资料,动手写了一个Demo.

原理

电话号码是用Call Directory extension事先存在系统里的,当来电时,系统会查询存储的数据, 根据号码绑定的label,决定直接屏蔽还是显示来电。

1240
iOS-CallKit.png
When using CallKit's Call Blocking & Identification feature (new in iOS 
10), phone numbers to be blocked or identified are loaded by your app's 
Call Directory extension prior to an incoming call and the phone numbers 
are stored by the system. Then, when an incoming call arrives, this stored 
data is consulted by the system and an incoming call may either be 
blocked or identified in the incoming call UI with the label provided.
For privacy and performance reasons, Call Directory app extensions are 
not launched when incoming calls arrive and an app extension cannot 
retrieve the phone number for an incoming call

http://stackoverflow.com/questions/38098036/how-to-get-the-incoming-call-number-by-using-callkit
https://www.zhihu.com/question/47542405

步骤

1 . 新建一个工程,New 一个 Target,选Call Directory Extension ,会自动生成模版代码。

  override func beginRequest(with context: CXCallDirectoryExtensionContext) {
        context.delegate = self

        do {
            try addBlockingPhoneNumbers(to: context)
        } catch {
            NSLog("Unable to add blocking phone numbers")
            let error = NSError(domain: "CallDirectoryHandler", code: 1, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }

        do {
            try addIdentificationPhoneNumbers(to: context)
        } catch {
            NSLog("Unable to add identification phone numbers")
            let error = NSError(domain: "CallDirectoryHandler", code: 2, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }

        NSLog("beginRequest context ", context);
        context.completeRequest()
    }

    private func addBlockingPhoneNumbers(to context: CXCallDirectoryExtensionContext) throws {
        // 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.
        //
         let phoneNumbers: [CXCallDirectoryPhoneNumber] = [ +8618005555555, +8618005555555 ]

        for phoneNumber in phoneNumbers {
            context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
        }
    }

    private func addIdentificationPhoneNumbers(to context: CXCallDirectoryExtensionContext) throws {
        // 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.
        let phoneNumbers: [CXCallDirectoryPhoneNumber] = [ +8618005555555, +8618005555555 ]
        let labels = [ "骚扰电话", "Local business" ]

        for (phoneNumber, label) in zip(phoneNumbers, labels) {
            context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)
        }
    }

2 . 手工给Extension 生成 一个 CallDirectoryExtension.entitlements 文件。
3 . 运行。在设备的设置 —> 电话 —> Call Blocking & Identification,开启我们的 App。
4 . 打电话

效果

1240
IMG_4610.png

API

beginRequest

该方法在 Containing App 调用 reload 或者在 设置 —> 电话 —> Call Blocking & Identification里开启权限的时候,会自动被调用。但是打断点的时候,无法进来。

open class CXCallDirectoryProvider : NSObject, NSExtensionRequestHandling {


    open func beginRequest(with context: CXCallDirectoryExtensionContext)
}

给系统数据库增加骚扰电话号码

    open func addBlockingEntry(withNextSequentialPhoneNumber 
phoneNumber: CXCallDirectoryPhoneNumber)
  • 数据量大时,需要分批处理,注意内存问题。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
  • 号码需要加区号。 Edit retrievePhoneNumbersToIdentifyAndLabels() to include the number and label you want. Add +CountryCode at the start (not confirmed yet if this is essential)

给系统数据库增加骚扰电话号码以及提示的文本

    open func addIdentificationEntry(withNextSequentialPhoneNumber phoneNumber:
 CXCallDirectoryPhoneNumber, label: String)

提交

    open func completeRequest(completionHandler completion:
 (@escaping (Bool) -> Swift.Void)? = nil)

苹果开发交流网站上的总结

https://forums.developer.apple.com/thread/48837

I've managed to get this working, here's what I did and 
some observations:

1) Create a new target of Type Call Directory Extension.

2) Edit retrievePhoneNumbersToIdentifyAndLabels() to include the number
 and label you want. Add +CountryCode at the start (not confirmed yet
 if this is essential)

3) Run the containing app target.

4) In setting go to Phone/Call Blocking & IdentificationAnd turn on you 
extension (or it will automatically be turned on if you run the
 entension target rather than the containing app target)

5) Make a call

Its not possible to hit any breakpoints in the extension if running in 
XCode regardless of which target you execute. NSLog statements can be 
viewed via XCode's devices, it indicates that the extension is called in 
step 4) if the above steps are called. I don't know if/when its called 
subsequently after that, it has to be otherwise how can an updated list
 be applied?

If you want to make a change to the label, the OS does caching, so turn
 off the extension, delete the containing app app, clear the call history
 from the phone app, install and run again.


相关文章
|
1月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
88 3
|
3月前
|
存储 iOS开发
iOS 开发,如何进行应用的本地化(Localization)?
iOS 开发,如何进行应用的本地化(Localization)?
122 2
|
3月前
|
存储 数据建模 数据库
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
IOS开发数据存储:什么是 UserDefaults?有哪些替代方案?
39 0
|
3月前
|
安全 编译器 Swift
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
IOS开发基础知识: 对比 Swift 和 Objective-C 的优缺点。
93 2
|
3月前
|
API 开发工具 iOS开发
iOS 开发高效率工具包:10 大必备工具
iOS 开发高效率工具包:10 大必备工具
48 1
|
3月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
54 1
|
8天前
|
API 定位技术 iOS开发
IOS开发基础知识:什么是 Cocoa Touch?它在 iOS 开发中的作用是什么?
【4月更文挑战第18天】**Cocoa Touch** 是iOS和Mac OS X应用的核心框架,包含面向对象库、运行时系统和触摸优化工具。它提供Mac验证的开发模式,强调触控接口和性能,涵盖3D图形、音频、网络及设备访问API,如相机和GPS。是构建高效iOS应用的基础,对开发者至关重要。
12 0
|
23天前
|
开发工具 Swift iOS开发
利用SwiftUI构建动态用户界面:iOS开发新范式
【4月更文挑战第3天】 随着苹果不断推进其软件开发工具的边界,SwiftUI作为一种新兴的编程框架,已经逐渐成为iOS开发者的新宠。不同于传统的UIKit,SwiftUI通过声明式语法和强大的功能组合,为创建动态且响应式的用户界面提供了一种更加简洁高效的方式。本文将深入探讨如何利用SwiftUI技术构建具有高度自定义能力和响应性的用户界面,并展示其在现代iOS应用开发中的优势和潜力。
|
2月前
|
监控 API Swift
用Swift开发iOS平台上的上网行为管理监控软件
在当今数字化时代,随着智能手机的普及,人们对于网络的依赖日益增加。然而,对于一些特定场景,如家庭、学校或者企业,对于iOS设备上的网络行为进行管理和监控显得尤为重要。为了满足这一需求,我们可以利用Swift语言开发一款iOS平台上的上网行为管理监控软件。
197 2
|
3月前
|
数据可视化 iOS开发
iOS 开发,什么是 Interface Builder(IB)?如何使用 IB 构建用户界面?
iOS 开发,什么是 Interface Builder(IB)?如何使用 IB 构建用户界面?
40 4