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

如何在CNContactPickerViewController中用predicateForEnablingContact筛选符合指定正则的联系人?

问题描述

需要在CNContactPickerViewController中通过predicateForEnablingContact,仅启用电话号码匹配正则表达式^\+1[2-9]\d{9}$的联系人(即联系人至少有一个号码符合该规则),但编写的NSPredicate始终触发无效错误。

尝试过的代码及对应错误:

  1. 第一种写法:
let predicate = NSPredicate(format: "ANY self.phoneNumbers.'value'.'stringValue' BEGINSWITH %@", "1111")
contactPicker.predicateForEnablingContact = predicate

错误日志:

2023-06-11 21:31:15.703957+0100 Test2[9610:702640] [CNUI ERROR] Error when showing picker: Error Domain=CNErrorDomain Code=300 "(null)" UserInfo={CNValidationErrors=(
"Error Domain=CNErrorDomain Code=400 "Invalid Predicate" UserInfo={NSLocalizedDescription=Invalid Predicate, NSLocalizedFailureReason=The operation couldn’t be completed because its predicate is invalid.}"

  1. 第二种写法:
NSPredicate(format: "phoneNumbers.@count > 0 AND SUBQUERY(phoneNumbers, $phoneNumber, $phoneNumber.value.stringValue != nil).@count > 0")

错误日志:

predicate is invalid., CNKeyPaths=(\n "value.stringValue"\n)}"


正确的NSPredicate写法

CNContactPickerViewController的predicateForEnablingContact对谓词语法有严格限制,不能随意使用嵌套属性访问,必须遵循联系人框架支持的键路径和操作符规则。

符合需求的正确写法如下:

let usPhoneRegex = "^\\+1[2-9]\\d{9}$"
let predicate = NSPredicate(format: "SUBQUERY(phoneNumbers, $num, $num.value.stringValue MATCHES %@).@count > 0", usPhoneRegex)
contactPicker.predicateForEnablingContact = predicate

核心说明

  • 必须用SUBQUERY遍历phoneNumbers数组,对每个号码单独做正则校验
  • 键路径$num.value.stringValue是框架允许的标准访问方式,避免了之前写法中不必要的单引号或格式错误
  • 使用MATCHES操作符对接正则表达式,直接匹配目标规则^\+1[2-9]\d{9}$
  • 通过@count > 0判断联系人是否存在至少一个符合规则的号码

该谓词能被联系人框架正确解析,只会启用满足号码规则的联系人。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:52:20