1

我正在尝试使用谓词:

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

它没有返回任何结果,所以我记录了它predicate.predicateFormat以确保谓词中包含正确的值。这显示了:

predicateForEnablingContact: organizationName == "%@"

如您所见,%@可替换参数没有被替换。

如果我在谓词中硬编码一个实际值以进行测试,则谓词可以正常工作。

我所能找到的似乎与我的问题远程相关的是这个 SO 问题: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 == %@”
*
第一次抛出调用stack: (0x1827d5d04 0x181a24528 0x1830e6fdc 0x1830e577c 0x101325144 0x101297ee0 0x1006a6724 0x1006a6cb4 0x18bd251c8 0x18bdce390 0x18be7cf68 0x18be7030c 0x18bbffabc 0x18277d848 0x18277b200 0x18277b7bc 0x18269bfb8 0x184533f84 0x18bc702e8 0x1006af6fc 0x1821be56c)
libc++abi.dylib: terminating with uncaught exception of type NSException

是的,我确实设置了异常断点 - 没有提供有关该问题的其他信息。正如我在评论中指出的那样,异常中断发生在let predicate = NSPredicate(format: "organizationName == %@", orgName).

那个中断是我加入引号的原因- 如果我有引号,它不会中断;它只是不返回任何结果。同样,记录谓词显示“无法解析...”消息中指示的相同字符串(在这种情况下包括引号除外)。

我也尝试用 and 替换==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什么,但我认为我有一个NSPredicate不喜欢的角色。我删除并重新输入(确切地说?)我分配值的代码orgName- 现在它在没有引号的情况下工作。我投票赞成当前的答案,因为响应者花时间考虑我的问题 - 并为这个问题的访问者提出了很好的观点。

4

3 回答 3

4

斯威夫特 4 - Xcode 9.1

尝试这个

let predicate = NSPredicate(format: "name contains[c] %@ ",searchString)
于 2017-12-25T16:41:05.773 回答
2

您应该删除引号。正如谓词编程指南所说:

单引号或双引号变量(或替换变量字符串)会导致 %@、%K 或 $variable 被解释为格式字符串中的文字,从而防止任何替换。

以下两项都对我有用predicateForEnablingContact。对于我使用的完全匹配:

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

或者,对于通配符搜索:

let orgName = "CREATIVE*"
let predicate = NSPredicate(format: "organizationName LIKE[CD] %@", orgName)
于 2017-12-23T13:45:03.393 回答
1

我认为您选择了错误的 init NSPredicate

初始化(格式:字符串,参数:CVaListPointer)

通过将参数列表中的值替换为格式字符串并解析结果来初始化谓词。

您可以参考NSPredicate的文档。

我已经为您尝试了相同的 init 查询:

var orgName = "xyz"
let predicate = NSPredicate(format: "organizationName == %@", orgName)
print(predicate) // organizationName == "xyz"
于 2017-12-23T05:52:37.150 回答