You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS中如何通过Call Directory Extension获取来电号码并调用API获取来电名称?

关于Call Directory Extension实时来电识别的解决方案

首先明确:Call Directory Extension本身不支持在来电触发时实时获取号码并调用API。它的设计逻辑是提前将号码与对应标签批量添加到系统,系统来电时直接匹配预加载条目,没有提供来电时刻的回调接口,无法实现你要的实时请求逻辑。

要实现“来电时实时获取号码并调用API获取数据”的需求,可通过以下替代方案实现:

替代方案:CXCallObserver监听来电 + 应用内展示

在主应用中利用CXCallObserver监听来电事件,检测到来电时获取号码,调用API后通过通知或自定义UI展示识别结果。

具体实现步骤

  1. 配置权限:在Info.plist中添加NSMicrophoneUsageDescription(CallKit依赖权限),并开启后台模式中的「Voice over IP」,确保应用后台也能监听来电。
  2. 实现来电监听逻辑:
import CallKit
import UserNotifications

class CallMonitor: NSObject, CXCallObserverDelegate {
    private let callObserver = CXCallObserver()
    
    override init() {
        super.init()
        callObserver.setDelegate(self, queue: DispatchQueue.main)
    }
    
    func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
        // 过滤出未接通的来电
        if !call.hasEnded && !call.isOutgoing && !call.hasConnected {
            guard let rawNumber = call.handle.value as? String else { return }
            let phoneNumber = rawNumber.trimmingCharacters(in: .whitespacesAndNewlines)
            
            // 调用API获取号码标签
            fetchLabel(for: phoneNumber) { label in
                guard let label = label else { return }
                // 弹出通知展示识别结果
                self.showCallNotification(phoneNumber: phoneNumber, label: label)
            }
        }
    }
    
    private func fetchLabel(for number: String, completion: @escaping (String?) -> Void) {
        // 替换为你的API请求地址
        guard let url = URL(string: "https://your-api-domain.com/lookup?number=\(number)") else {
            completion(nil)
            return
        }
        
        let task = URLSession.shared.dataTask(with: url) { data, _, error in
            guard let data = data, error == nil else {
                completion(nil)
                return
            }
            
            // 解析API返回的标签(示例为JSON格式)
            if let result = try? JSONSerialization.jsonObject(with: data) as? [String: String],
               let label = result["label"] {
                completion(label)
            } else {
                completion(nil)
            }
        }
        task.resume()
    }
    
    private func showCallNotification(phoneNumber: String, label: String) {
        let content = UNMutableNotificationContent()
        content.title = "来电识别"
        content.body = "\(phoneNumber):\(label)"
        content.sound = UNNotificationSound.default
        
        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
        UNUserNotificationCenter.current().add(request)
    }
}
  1. 初始化监听:在AppDelegate或SceneDelegate中启动监听:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 初始化来电监听
    _ = CallMonitor()
    
    // 请求通知权限
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { granted, _ in
        if granted {
            DispatchQueue.main.async {
                application.registerForRemoteNotifications()
            }
        }
    }
    return true
}

注意事项

  • 后台限制:iOS对后台应用活动限制严格,若应用被系统杀死,CXCallObserver可能无法监听到来电。可结合PushKit静默推送唤醒应用,但需额外配置。
  • 号码格式:API请求时需统一号码格式(比如带国际区号),避免因格式不匹配导致查询失败。
  • API响应速度:需确保API能在来电响铃的短时间内返回结果,否则用户可能看不到识别信息。

内容的提问来源于stack exchange,提问作者Iftikhar Hussain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:23:10