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

iOS获取联系人姓名部分设备崩溃:Unrecognized selector异常求助

崩溃原因及解决方案

核心崩溃原因

部分旧iOS系统版本的Contacts框架不支持将NSCompoundPredicate作为CNContactFetchRequest的查询谓词使用。CNContact.predicateForContacts(matching:)返回的是Contacts框架专属的CNPredicate子类实例,你用NSCompoundPredicate对其包装后,框架内部尝试调用仅CNPredicate子类才有的cn_triageWithLog:serialNumber:方法,而NSCompoundPredicate未实现该方法,因此触发NSInvalidArgumentException崩溃。

另外,你的代码里用NSCompoundPredicate包装单个谓词完全是冗余操作——仅需单个查询条件时,根本不需要复合谓词组合。

修改后的代码

func getContactName(phoneNumber: String, completion: @escaping (String) -> Void ) {
    let phoneNumber = CNPhoneNumber(stringValue: phoneNumber)
    let phoneNumberPredicate = CNContact.predicateForContacts(matching: phoneNumber)
    
    let fetchRequest = CNContactFetchRequest(keysToFetch: [
        CNContactGivenNameKey as CNKeyDescriptor,
        CNContactFamilyNameKey as CNKeyDescriptor
    ])
    // 直接使用单个谓词,去掉冗余的NSCompoundPredicate包装
    fetchRequest.predicate = phoneNumberPredicate
    
    let store = CNContactStore()
    do {
        try store.enumerateContacts(with: fetchRequest) { (contact, stop) in
            let contactName = contact.givenName
            completion(contactName)
            // 找到匹配项后立即停止枚举,提升性能
            stop.pointee = true
        }
    } catch {
        // 补充错误处理,避免调用者一直等待
        completion("")
    }
}

额外优化建议

  1. 找到第一个匹配联系人后设置stop.pointee = true,避免遍历所有联系人,提升查询效率。
  2. 不要忽略错误处理,至少在catch块中给completion返回默认值,避免调用方出现异常。

内容的提问来源于stack exchange,提问作者Joice George

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:40:18