Swift:UISearchBar,通过 NSPredicate 名字或姓氏查找 Person

Posted

技术标签:

【中文标题】Swift:UISearchBar,通过 NSPredicate 名字或姓氏查找 Person【英文标题】:Swift: UISearchBar, find Person by NSPredicate first or last name 【发布时间】:2019-12-10 16:13:41 【问题描述】:

我正在尝试通过姓氏或名字来查找具有 UISearchbar 的人。

我已经实现了以下代码:

   func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 
        let request: NSFetchRequest<Person> = Person.fetchRequest()

        let searchTerm = searchBar.text
        if searchTerm != "" 

            let predicateLastname = NSPredicate(format: "nachname CONTAINS[cd] %@,", searchTerm!)
            let precicateFirstname = NSPredicate(format: "vorname CONTAINS [cd] %@", searchTerm!)

            let predicateOr = NSCompoundPredicate(type: .or, subpredicates: [predicateLastname, precicateFirstname])

            request.predicate = predicateOr

            let sortDecriptor = NSSortDescriptor(key: "nachname", ascending: true)
            let sortDecriptor2 = NSSortDescriptor(key: "vorname", ascending: true)
            request.sortDescriptors = [sortDecriptor, sortDecriptor2]
        
        do 
            let personArray = try managedObjectContext!.fetch(request) as! [NSManagedObject]

         catch 
            ("Error searching person \(error)")
        

        tableView.reloadData()
    

如果我运行程序会发生错误:

2019-12-10 17:07:56.641142+0100 HappyBirthdayMom[13999:810809] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "nachname CONTAINS[cd] %@,"'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff23c4f02e __exceptionPreprocess + 350
    1   libobjc.A.dylib                     0x00007fff50b97b20 objc_exception_throw + 48
    2   Foundation                          0x00007fff257d7a31 +[NSPredicate predicateWithFormat:arguments:] + 164
    3   libswiftFoundation.dylib            0x00007fff515388bf $sSo12NSExpressionC10FoundationE6format_ABSSh_s7CVarArg_pdtcfCTm + 543
    4   HappyBirthdayMom                    0x000000010797bc1c $s16HappyBirthdayMom20MasterViewControllerC28searchBarSearchButtonClickedyySo08UISearchH0CF + 1004
    5   HappyBirthdayMom                    0x000000010797c944 $s16HappyBirthdayMom20MasterViewControllerC28searchBarSearchButtonClickedyySo08UISearchH0CFTo + 68
    6   UIKitCore                           0x00007fff46f17c8d -[UISearchBar(UISearchBarStatic) _searchFieldReturnPressed] + 72
    7   UIKitCore                           0x00007fff47850dfa -[UIApplication sendAction:to:from:forEvent:] + 83
    8   UIKitCore                           0x00007fff4722ac22 -[UIControl sendAction:to:forEvent:] + 223
    9   UIKitCore                           0x00007fff4722af6c -[UIControl _sendActionsForEvents:withEvent:] + 398
    10  UIKitCore                           0x00007fff47b3b867 -[UIFieldEditor insertFilteredText:] + 298
    11  UIKitCore                           0x00007fff47b593cf -[UITextField insertFilteredText:] + 93
    12  UIKitCore                           0x00007fff46f20de4 -[UISearchTextField insertFilteredText:] + 80
    13  UIKitCore                           0x00007fff47666421 -[UIKeyboardImpl insertText:] + 147
    14  UIKitCore                           0x00007fff47660c19 -[UIKeyboardImpl _performKeyboardOutput:shouldCheckDelegate:] + 1059
    15  UIKitCore                           0x00007fff4765f84d __55-[UIKeyboardImpl handleKeyboardInput:executionContext:]_block_invoke_2 + 372
    16  UIKitCore                           0x00007fff4768ee0d -[UIKeyboardTaskEntry execute:] + 147
    17  UIKitCore                           0x00007fff4768d923 -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 310
    18  Foundation                          0x00007fff25761c40 __NSThreadPerformPerform + 259
    19  CoreFoundation                      0x00007fff23bb2221 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    20  CoreFoundation                      0x00007fff23bb214c __CFRunLoopDoSource0 + 76
    21  CoreFoundation                      0x00007fff23bb1924 __CFRunLoopDoSources0 + 180
    22  CoreFoundation                      0x00007fff23bac62f __CFRunLoopRun + 1263
    23  CoreFoundation                      0x00007fff23babe16 CFRunLoopRunSpecific + 438
    24  GraphicsServices                    0x00007fff38438bb0 GSEventRunModal + 65
    25  UIKitCore                           0x00007fff4784fb48 UIApplicationMain + 1621
    26  HappyBirthdayMom                    0x00000001079869cb main + 75
    27  libdyld.dylib                       0x00007fff51a1dc25 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

该函数应按姓氏或名字搜索 Person ,顺序无关紧要。 非常感谢

【问题讨论】:

不应该是这样的:let predicateLastname = NSPredicate(format: "%@ CONTAINS[cd] %@,", nachname, searchTerm!) 但是我不知道 nachname 或 vorname 是从哪里来的。 两个String属性都来自实体类person——由Core Data管理 您是否尝试过在我的第一条评论中提取vorname 并替换为%@?我试图为你找到一个具体的例子。如果我成功了会发布它。 试过了,但据我所知 - NSPredicate 只允许 2 个参数。欣赏它 - 谢谢你 "nachname CONTAINS[cd] %@,中,去掉最后的逗号,应该可以了。 【参考方案1】:

这就是错误所在:

let predicateLastname = NSPredicate(format: "nachname CONTAINS[cd] %@,", searchTerm!)

事实上,如果你只使用那个谓词,你仍然会得到错误。

不要放“,”:

let predicateLastname = NSPredicate(format: "nachname CONTAINS[cd] %@", searchTerm!)

如果逗号需要出现在搜索文本中(原因不明),

let predicateLastname = NSPredicate(format: "nachname CONTAINS[cd] %@", searchTerm! + ",")

【讨论】:

解决了错误 - 谢谢,但由于某种原因,tableview 不显示搜索的术语。我在代码中遗漏了什么。在和我重新加载数据。

以上是关于Swift:UISearchBar,通过 NSPredicate 名字或姓氏查找 Person的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UiSearchBar 的背景颜色更改为黑色-SWIFT

UISearchBar:传递数据;单击的标题与 ListViewController - Swift 中显示的数据不对应

在 Swift 4 中自定义 UISearchBar

NavigationItem + UISearchBar 与 Swift

Swift:UISearchBar:单击搜索按钮时获取文本

使用 Swift 过滤 UISearchBar 的核心数据