我试着用一个谓词:

let predicate = NSPredicate(format: "organizationName == '%@'", orgName)

它没有返回任何结果,所以我记录了predicate.predicateFormat以确保谓词中有正确的值。它表明:
predicateForEnablingContact: organizationName == "%@"

如您所见,%@可替换参数没有被替换。
如果我在谓词中硬编码一个实际值,以进行测试,则谓词可以正常工作。
我所能找到的似乎与我的问题无关的就是这个问题:iOS 11 NSPredicate search on Swift array crashing - NSUnknownKeyException。解决方案表明,谓词可能与@objc推理更改有一些问题。
不过,我不认为其他人有这个问题。最近有一些与谓词相关的问题具有选定的答案,例如这个问题,它显示使用了一个可替换的参数:Swift: 'IN' query alternative using NSPredicate for fetching records from iCloud
我只是错过了一些简单的事情吗???
我的代码,以防引起其他想法:
let contactPicker = CNContactPickerViewController()
contactPicker.delegate = self;

contactPicker.displayedPropertyKeys = [CNContactPhoneNumbersKey]

let predicate = NSPredicate(format: "organizationName == '%@'", orgName)

os_log("orgName = %{public}@\tpredicateForEnablingContact: %{public}@", log: debugLog, type: .debug, title, predicate.predicateFormat)

contactPicker.predicateForEnablingContact = predicate
present(contactPicker, animated: true, completion: nil)

联系人选择器出现;但是没有选择任何项-再次,除非我将orgName值硬编码到谓词中。然后,启用正确的联系人。
更新:
如果删除引号,将得到一个signal SIGABRT并显示以下消息:
2017-12-23 12:35:56.871282-0600 MyApp[1337:1170156]*由于意外异常“NSInvalidArgumentException”而终止应用,原因:“无法分析格式字符串”organizationName=%@“
*第一个抛出调用堆栈:
(0x1827d5d04 0x181a24528 0x1830e6fdc 0x1830e577c 0x101325144 0x101297ee0 0x1006a6724 0x1006a6cb4 0x18bd251c8 0x18bdce390 0x18be7cf68 0x18be7030c 0x18bbffabc 0x18277d848 0x18277b200 0x18277b7bc 0x18269bf8 0x184533f84 0x18bc702e8 0x1006af6fc 0x1821be56c)
libc++abi.dylib:以NSException类型的意外异常终止
是的,我确实设置了异常断点-没有提供有关此问题的其他信息。正如我在评论中指出的,异常中断发生在let predicate = NSPredicate(format: "organizationName == %@", orgName)行。
这个中断是我把引号放进去的原因——如果我有引号,它不会中断;它只是不返回任何结果。同样,记录谓词会显示“无法分析…”消息中指示的相同字符串(在这种情况下包括引号)。
我还尝试用==CONTAINS[c]替换MATCHES[c],结果相同。当然,无论如何,它都应该与==一起工作。
更新2:
FWIW,我使用的是Xcode版本9.2(9C40b)
Swift --version显示:
Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2)
Target: x86_64-apple-macosx10.9

更新3:提出这个问题,以防我的评论消失:
啊。。。我不知道到底发生了什么,但我想我有一个不喜欢的角色。我删除并重新键入(确切地说?)我把值赋给orgName的代码,现在它不用引号了。我投票支持当前的答案,因为响应者花了时间考虑我的问题-并为这个问题的访问者提供了很好的观点。

最佳答案

你应该去掉引号。正如Predicate Programming Guide所说:
单引号或双引号变量(或替换变量字符串)会导致将%@、%K或$variable解释为格式字符串中的文本,从而防止任何替换。
以下两种方法都适用于predicateForEnablingContact。对于我使用的精确匹配:

let orgName = "Apple"
let predicate = NSPredicate(format: "organizationName == %@", orgName)

或者,对于通配符搜索:
let orgName = "CREATIVE*"
let predicate = NSPredicate(format: "organizationName LIKE[CD] %@", orgName)

关于ios - NSPredicate不替换%@参数-Swift 4,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47949903/

10-14 09:01
查看更多