简体   繁体   English

Cloudkit的NSPredicate匹配字符串

[英]NSPredicate matching string for Cloudkit

I need to pull the record from cloudkit matching a string. 我需要从cloudkit中提取与字符串匹配的记录。

I have a User record type, with an email field. 我有一个用户记录类型,带有一个电子邮件字段。 I have multiple records with the same email, but I can't get the predicate to get me the records. 我有多条记录使用同一封电子邮件,但是我无法断言要获取这些记录。

I've tried all of these: 我已经尝试了所有这些方法:

let predicate = NSPredicate(format: "email = 'julio_ukohgsp_chevez@tfbnw.net'")
NSPredicate(format: "email == %@", argumentArray: [email])
NSPredicate(format: "email IN %@", [email])
NSPredicate(format: "email contains %@", email)
NSPredicate(format: "email = %@", email)
NSPredicate(format: "email == %@", email)

My query specifies the record type: 我的查询指定记录类型:

let query = CKQuery(recordType: "User", predicate: NSPredicate(format: "email == %@", email))

When I do a predicate with value: true, I get all records including the one I want.. I know for sure I have a User with that email, multiple in fact.. 当我用值做一个谓词:true时,我会得到所有记录,包括我想要的记录。.我当然知道我有一个使用该电子邮件的用户,实际上是多个。

What am I missing? 我想念什么?

Edit .. 编辑..

let query = CKQuery(recordType: "User", predicate: NSPredicate(format: "email BEGINSWITH %@", email))

Does work and brings back records, but I want an exact match! 确实有效并带回了记录,但我想要完全匹配!

I had same issue and was able to resolve it by adding Queryable index on user field in my case. 我遇到了同样的问题,并且能够通过在我的情况下在用户字段上添加Queryable索引来解决此问题。 Note, after index was added I needed to write data again to CloudKit to be able to perform query. 注意,添加索引后,我需要再次将数据写入CloudKit才能执行查询。

Code for creation of predicate: 谓词创建代码:

let user = "test-user"
let userPredicate = NSPredicate(format: "user == %@", user)

I've been having this same issue with one of my apps. 我的一个应用程序遇到了同样的问题。 In my case, I needed to subscribe to a list of predicates where a lot of search criteria needed to be met but the search or filter predicate gave me the most trouble. 就我而言,我需要订阅一个谓词列表,其中需要满足许多搜索条件,但搜索或过滤谓词给我带来了最大的麻烦。 I also tried: 我也尝试过:

let word1 = "Mac"

let predicate = NSPredicate(format: "Title CONTAINS %@", word1)

This worked but only when 'word1' was a single word with no spaces and 'Title' was a 'String List' in the cloud. 这是可行的,但是仅当“ word1”是一个没有空格的单个单词,而“ Title”是云中的“字符串列表”时才有效。

The clarification that I have come across in all my research is: 我在所有研究中都遇到的问题是:

You need to use the term 'self' when you create a predicate and what that does is it searches all the fields that are a searchable string. 创建谓词时,需要使用“自我”一词,它会搜索所有可搜索字符串的字段。 Here is the information I got from Apple's Website. 这是我从Apple网站获得的信息

Predicates support the following variable substitution strings: 谓词支持以下变量替换字符串:

Use %@ for value objects such as strings, numbers, and dates. 将%@用于值对象,例如字符串,数字和日期。

Use %K for the name of a field. 使用%K作为字段名称。 This substitution variable indicates that the substituted string should be used to look up a field name. 此替换变量指示应使用替换的字符串来查找字段名称。

With one exception, the CONTAINS operator can be used only to test list membership. 除了一个例外,CONTAINS运算符只能用于测试列表成员资格。 The exception is when you use it to perform full-text searches in conjunction with the self key path. 例外是当您使用它与自键路径一起执行全文搜索时。 The self key path causes the server to look in searchable string-based fields for the specified token string. 自我密钥路径使服务器在基于可搜索字符串的字段中查找指定的令牌字符串。 For example, a predicate string of @"self contains 'blue'" searches for the word “blue” in all fields marked for inclusion in full-text searches. 例如,谓词字符串@“ self包含'blue'”在所有标记为包含在全文搜索中的字段中搜索单词“ blue”。 You cannot use the self key path to search in fields whose type is not a string. 您不能使用自密钥路径搜索类型不是字符串的字段。

What I ended up doing, which there has to be a better way, is my 'Title' property is still a 'String List' in the cloud and in my code I made an array of all the words in my searchTerm and with each word in the searchTerm I made a separate NSPredicate and I used those as part of a NSCompoundPredicate. 我最终要做的是,必须有一个更好的方法,就是我的“标题”属性仍然是云中的“字符串列表”,在我的代码中,我对searchTerm中的所有单词进行了数组,每个单词在searchTerm中,我制作了一个单独的NSPredicate,并将它们用作NSCompoundPredicate的一部分。 I then added the NSCompoundPredicate to my subscription and it worked. 然后,我将NSCompoundPredicate添加到我的订阅中,并且可以正常工作。 Here is my example: 这是我的示例:

var searchCriteria: [NSPredicate] = []

for word in searchTerm {
    let predicate = NSPredicate(format: "self CONTAINS %@", word)
    searchCriteria.append(predicate)
}

let p2 = NSPredicate(format: "Price > %d", minPrice)

let p3 = NSPredicate(format: "Price < %d", maxPrice)

let p4 = NSPredicate(format: "Category == %d", category)

searchCriteria.append(p2)
searchCriteria.append(p3)
searchCriteria.append(p4)

let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: searchCriteria)

I hope this helps. 我希望这有帮助。 There has to be a better way to do this and if anyone knows, please let me know cause I understand there isn't a lot of good explanations on how to do things with CloudKit. 必须有一种更好的方法来进行此操作,如果有人知道,请让我知道,因为我知道关于如何使用CloudKit进行操作的解释不多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM