使用Swift和Core Data的NSPredicate

19

我有一个Core Data对象,其中有两个字段(一个字符串GUID和一个整数,我想用它作为筛选器)

在SQL中,它会是"SELECT * FROM Answers WHERE qIndex = 1 AND GUID = '88bfd206-82fb-4dd0-b65d-096f8902855c'

我尝试使用Core Data,但无法使用字符串值进行过滤。

这是我的代码:

    var request = NSFetchRequest(entityName: "Answers")
    request.returnsObjectsAsFaults = false;

    let resultPredicate1 = NSPredicate(format: "qIndex = %i", qIndex)
    let resultPredicate2 = NSPredicate(format: "formUUID = %s", formUUID)

    var compound = NSCompoundPredicate.andPredicateWithSubpredicates([resultPredicate1, resultPredicate2])
    request.predicate = compound


    var results:NSArray = context.executeFetchRequest(request, error: nil)

有什么想法我做错了什么吗?对于两个整数值使用相同的代码和筛选器时,它可以正常工作。

提前感谢。


1
你使用了字符串格式说明符%i。我认为应该使用%d表示十进制或者使用%@表示NSNumber。不应该使用不存在的int类型 %i。 - Obenland
1
@Xean:使用“%d”和“%i”都可以格式化整数,它们是相同的。 - Martin R
为什么当没有匹配项时,结果不为空?我得到了[<ChartModel: 0x1740b6c20>(实体:Charts;ID:0xd000000000040000 x-coredata://F542870C-1070-40D2-BC59-8FCE71D18224/Charts/p1;数据:<fault>)] - Ace Green
并且结果计数大于0吗? - derdida
最好实际检查您的数据,因为它会减少对象图的内存占用。这还可以让您仅加载所需的内容。如果您正在使用fetchRequest预取其他字段,则这些值将被填充而不是错误。 - TheM00s3
2
顺便提一下,由于Swift支持字符串插值,您不再需要使用老式的格式化变量样式,可以将NSPredicate(format: "qIndex = %i", qIndex)替换为NSPredicate(format: "qIndex = \(qIndex)") - Fyodor Volchyok
3个回答

43
如果formUUID是一个NSString或者Swift中的String,那么你需要使用%@作为占位符:
let resultPredicate2 = NSPredicate(format: "formUUID = %@", formUUID)

1
编辑建议:谓词字符串中可以使用=== - Martin R

8

这不是对你问题的确切回答,而是人们现在可能会遇到的代码问题:

在最新版本的XCode中,您现在必须解开谓词,像这样:

var compound = NSCompoundPredicate.andPredicateWithSubpredicates([predicate1!, predicate2!])

由于 NSPredicate 初始化器现在返回 NSPredicate? 类型,因此需要进行相应的更改。

1
正如你自己所说,这并不是一个真正的答案,而只是一条注释。因此,你应该将其添加为评论,而不是作为答案。 - JohannesB
7
没错,但我只在StackOverflow上注册了几周,我的声望(1)不允许我评论别人的问题/答案;) - DarksteelPenguin

1

不必担心%@转换和组合AND谓词,您可以使用PredicatePal框架:

let compound = *(Key("qIndex") == qIndex && Key("formUUID") == formUUID)

假设qIndexformUUID是正确的类型,Swift将自动推断Key对象的正确类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接