我已经解决了如何搜索我的CKrecord并仅使用以下代码从一个字段显示字符串。
我有几个问题。(我是新来的)
我可以搜索,并且不区分大小写吗?
如何搜索记录中的所有字段,然后在匹配项上显示所有字段?
我正在制作参考应用程序,因此您可以搜索例如BBC1,以及与BBC1相关的所有内容(即在该recordID中)。
Dashboard.jpg showing Record and Fields
import UIKit
import CloudKit
import MobileCoreServices
class ViewController: UIViewController {
@IBOutlet var addressField: UITextField!
@IBOutlet var commentsField: UITextView!
let container = CKContainer.defaultContainer()
var publicDatabase: CKDatabase?
var currentRecord: CKRecord?
override func viewDidLoad() {
publicDatabase = container.publicCloudDatabase
super.viewDidLoad()
}
@IBAction func performQuery(sender: AnyObject) {
let predicate = NSPredicate(format: "serviceName = %@", addressField.text!)
let query = CKQuery(recordType: "SystemFields", predicate: predicate)
publicDatabase?.performQuery(query, inZoneWithID: nil, completionHandler: ({results, error in
if(error != nil) {
dispatch_async(dispatch_get_main_queue()) {
self.notifyUser("Cloud Access Error",
message: error!.localizedDescription)
}
} else {
if results!.count > 0 {
let record = results![0]
self.currentRecord = record
dispatch_async(dispatch_get_main_queue()) {
self.commentsField.text = record.objectForKey("Location") as! String
}
} else { dispatch_async(dispatch_get_main_queue()) {
self.notifyUser("No Match Found",
message: "No record matching the address was found")
}
}
}
}))
}
func notifyUser(title: String, message: String) -> Void
{
let alert = UIAlertController(title: title,
message: message,
preferredStyle: UIAlertControllerStyle.Alert)
let cancelAction = UIAlertAction(title: "OK",
style: .Cancel, handler: nil)
alert.addAction(cancelAction)
self.presentViewController(alert, animated: true,
completion: nil)
}
}
Print Results Output
最佳答案
根据Apple的CKQuery Class Reference,您应该能够通过对记录的字段进行标记化搜索来完成这两项操作:
要对记录的字段执行标记化搜索,请使用特殊运算符self
。标记化搜索将搜索所有启用了全文本搜索的字段,默认情况下是所有基于字符串的字段。为了搜索的目的,标记化字符串中的每个不同单词都被视为一个单独的标记。比较不区分大小写和变音符号。这些令牌字符串可以在单个字段或多个字段中找到。
这是清单5的示例(在Swift中):
清单5-匹配包含一个或多个令牌的字段
var predicate = NSPredicate(format: "self contains 'bob smith'")
还有清单6的示例(在Swift中):
清单6-匹配包含多个令牌的字段
var predicate = NSPredicate(format: "self contains 'bob' AND self contains 'smith'")
最后,查看Indexes and Full-Text Search上的信息,因为CloudKit中的记录配置会影响要搜索的字段(和性能)。
编辑:您的用例的进一步说明:
由于您使用的是addressField.text的内容来执行搜索...
您必须决定是否要匹配:
选项1 -
当addressField.text中的任何单个单词与记录中任何字段中的任何单词匹配时。
在Swift 2.2中:
let predicate = NSPredicate(format: "self contains %@", addressField.text!)
选项2-
当addressField.text中的所有单词都在记录的一个字段中时(尽管不一定以相同的顺序)。
在Swift 2.2中:
// creates a compound predicate to match all words in a string
// returns: nil if input was empty, otherwise an NSPredicate
func createPredicateForMatchingAllWordsIn(string: String) -> NSPredicate?
{
guard !string.isEmpty else { return nil }
var predicateList : [NSPredicate] = []
let words = string.componentsSeparatedByString(" ")
for word in words {
if !word.isEmpty {
predicateList.append(NSPredicate(format: "self contains %@", word))
}
}
return NSCompoundPredicate(andPredicateWithSubpredicates: predicateList)
}
let predicate = createPredicateForMatchingAllWordsIn(addressField.text!)
如果您想进行其他过滤,例如仅显示单词顺序匹配的记录,则可以在客户端进行过滤。 (CKQuery类仅支持完整NSPredicate类提供的谓词行为的子集。)