我已经解决了如何搜索我的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类提供的谓词行为的子集。)

10-08 05:29
查看更多