Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用CNContacts(Swift)实现搜索控制器时出现问题_Ios_Swift_Uitableview_Uisearchcontroller_Cncontact - Fatal编程技术网

Ios 使用CNContacts(Swift)实现搜索控制器时出现问题

Ios 使用CNContacts(Swift)实现搜索控制器时出现问题,ios,swift,uitableview,uisearchcontroller,cncontact,Ios,Swift,Uitableview,Uisearchcontroller,Cncontact,我正在开发一个小应用程序,我想实现一个搜索控制器,能够对我检索到的联系人进行查询。我已成功检索系统联系人并将其显示在表视图中。但是当我试图实现一个搜索控制器来简化联系人的搜索时,我遇到了一个“无效谓词”问题,我不知道如何解决它 这是我的实际做法: import UIKit import Contacts class PhoneContactsVC: UITableViewController { var contactsArray = [CNContact]() var co

我正在开发一个小应用程序,我想实现一个搜索控制器,能够对我检索到的联系人进行查询。我已成功检索系统联系人并将其显示在表视图中。但是当我试图实现一个搜索控制器来简化联系人的搜索时,我遇到了一个“无效谓词”问题,我不知道如何解决它

这是我的实际做法:

import UIKit
import Contacts

class PhoneContactsVC: UITableViewController {

    var contactsArray = [CNContact]()
    var contacts = [CNContact]()
    var selectedContactCN = CNContact()
    var searchController: UISearchController!
    var searchResults = [CNContact]()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self as UITableViewDelegate
        tableView.dataSource = self
        let store = CNContactStore()
        retrieveContacts(from: store)
        setColors()
        let searchResultsController = UITableViewController(style: .insetGrouped)
        searchResultsController.tableView.delegate = self
        searchResultsController.tableView.dataSource = self
        searchResultsController.tableView.rowHeight = 63
        searchResultsController.tableView.register(FriendCell.self, forCellReuseIdentifier: "FriendCell")
        searchController = UISearchController(searchResultsController: searchResultsController)
        searchController.searchResultsUpdater = self
        searchController.searchBar.sizeToFit()
        searchController.searchBar.tintColor = .systemGreen
        searchController.searchBar.delegate = self
        searchController.searchBar.barTintColor = .systemGreen
        definesPresentationContext = true
        navigationItem.searchController = searchController

    }

    override func willMove(toParent parent: UIViewController?) { // tricky part in iOS 10
        navigationController?.navigationBar.barTintColor = UIColor.systemGreen //previous color
        super.willMove(toParent: parent)
    }

    private func setColors(){
        navigationController?.navigationBar.barTintColor = UIColor.white
        let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.black]
        navigationController?.navigationBar.titleTextAttributes = textAttributes
        navigationController?.navigationBar.tintColor = UIColor.systemBlue;
    }

    func filterResultsWithSearchString(searchString: String) {
        let predicate: NSPredicate = CNContact.predicateForContacts(matchingName: searchString)
        let keysToFetch = [CNContactGivenNameKey as CNKeyDescriptor, CNContactFamilyNameKey as CNKeyDescriptor, CNContactImageDataAvailableKey as CNKeyDescriptor, CNContactBirthdayKey as CNKeyDescriptor, CNContactImageDataKey as CNKeyDescriptor, CNContactPhoneNumbersKey as CNKeyDescriptor]
        searchResults = try! CNContactStore().unifiedContacts(matching: predicate, keysToFetch: keysToFetch)

    }


func retrieveContacts(from store: CNContactStore) {
  let containerId = store.defaultContainerIdentifier()
  let predicate = CNContact.predicateForContactsInContainer(withIdentifier: containerId)
  // 4
  let keysToFetch = [CNContactGivenNameKey as CNKeyDescriptor, CNContactFamilyNameKey as CNKeyDescriptor, CNContactImageDataAvailableKey as CNKeyDescriptor, CNContactBirthdayKey as CNKeyDescriptor, CNContactImageDataKey as CNKeyDescriptor, CNContactPhoneNumbersKey as CNKeyDescriptor]
  contactsArray = try! store.unifiedContacts(matching: predicate, keysToFetch: keysToFetch)
    contacts = contactsArray.sorted(by: {$0.givenName < $1.givenName})
    contacts.removeAll(where: {$0.givenName == ""})
  DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
    }
}
}

extension PhoneContactsVC: UISearchBarDelegate {
}

extension PhoneContactsVC: UISearchResultsUpdating {
  func updateSearchResults(for searchController: UISearchController) {
    let searchString = searchController.searchBar.text!
    filterResultsWithSearchString(searchString: searchString)

    let searchResultsController = searchController.searchResultsController as! UITableViewController
    searchResultsController.tableView.reloadData()
  }
}

extension PhoneContactsVC {
  // 1
  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return contacts.count
  }

  // 2
  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // 3
    let cell = self.tableView.dequeueReusableCell(withIdentifier: "ContactTableViewCell") as! ContactTableViewCell
    let contact = searchController.isActive ? searchResults[indexPath.row] : contacts[indexPath.row]

    if contact.birthday == nil {
        cell.registeredBday.isHidden = true
    }
    else {
        cell.registeredBday.isHidden = false
    }
    cell.nameLabel.text = "\(contact.givenName) \(contact.familyName)"

    // 4
    if contact.imageDataAvailable == true, let imageData = contact.imageData {
      cell.contactImage.image = UIImage(data: imageData)
    }
    else {
        cell.contactImage.image = UIImage(named: "MaLong")
    }
    return cell
  }

  override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath{
    selectedContactCN = contacts[indexPath.row]
    return indexPath
  }
}
导入UIKit
导入联系人
类PhoneContactsVC:UITableViewController{
var contactsArray=[CNContact]()
变量触点=[CNContact]()
var selectedContactCN=CNContact()
var searchController:UISearchController!
var searchResults=[CNContact]()
重写func viewDidLoad(){
super.viewDidLoad()
tableView.delegate=自身作为UITableViewDelegate
tableView.dataSource=self
let store=CNContactStore()
retrieveContacts(来自:存储)
setColors()
让searchResultsController=UITableViewController(样式:.InsetGroup)
searchResultsController.tableView.delegate=self
searchResultsController.tableView.dataSource=self
searchResultsController.tableView.rowHeight=63
searchResultsController.tableView.register(FriendCell.self,forCellReuseIdentifier:“FriendCell”)
searchController=UISearchController(searchResultsController:searchResultsController)
searchController.SearchResultsUpdate=self
searchController.searchBar.sizeToFit()
searchController.searchBar.tintColor=.systemGreen
searchController.searchBar.delegate=self
searchController.searchBar.barTintColor=.systemGreen
DefinePresentationContext=true
navigationItem.searchController=searchController
}
重写func willMove(toParent父对象:UIViewController?{///iOS 10中的棘手部分
navigationController?.navigationBar.barTintColor=UIColor.systemGreen//上一颜色
super.willMove(家长:家长)
}
私有func setColors(){
navigationController?.navigationBar.barTintColor=UIColor.white
让textAttributes=[NSAttributedString.Key.foregroundColor:UIColor.black]
navigationController?.navigationBar.titleTextAttributes=textAttributes
navigationController?.navigationBar.tintColor=UIColor.systemBlue;
}
func filterResultsWithSearchString(searchString:String){
let谓词:NSPredicate=CNContact.predicateForContacts(匹配名称:searchString)
让KeyFetch=[CNContactGivenNameKey作为CNKeyDescriptor,CNContactFamilyNameKey作为CNKeyDescriptor,CNContactImageDataAvailableKey作为CNKeyDescriptor,CNContactBirthdayKey作为CNKeyDescriptor,CNContactImageDataKey作为CNKeyDescriptor,CNContactPhoneNumbersKey作为CNKeyDescriptor]
searchResults=try!CNContactStore().unifiedContacts(匹配:谓词,keystefetch:keystefetch)
}
func retrieveContacts(来自存储:CNContactStore){
让containerId=store.defaultContainerIdentifier()
let predicate=CNContact.predicateForContactsInContainer(带标识符:containerId)
// 4
让KeyFetch=[CNContactGivenNameKey作为CNKeyDescriptor,CNContactFamilyNameKey作为CNKeyDescriptor,CNContactImageDataAvailableKey作为CNKeyDescriptor,CNContactBirthdayKey作为CNKeyDescriptor,CNContactImageDataKey作为CNKeyDescriptor,CNContactPhoneNumbersKey作为CNKeyDescriptor]
contactsArray=try!store.unifiedContacts(匹配:谓词,keystefetch:keystefetch)
contacts=contactsArray.sorted(按:{$0.givenName<$1.givenName})
contacts.removeAll(其中:{$0.givenName==“”})
DispatchQueue.main.async{[weak self]位于
self?.tableView.reloadData()
}
}
}
分机电话联系人SVC:UISearchBarDelegate{
}
扩展电话联系人svc:UISearchResultsUpdating{
func updateSearchResults(对于searchController:UISearchController){
让searchString=searchController.searchBar.text!
filterResultsWithSearchString(searchString:searchString)
让searchResultsController=searchController.searchResultsController为!UITableViewController
searchResultsController.tableView.reloadData()
}
}
分机{
// 1
重写func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
返回联系人数
}
// 2
重写func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
// 3
将cell=self.tableView.dequeueReusableCell(标识符为“ContactTableViewCell”)设为!ContactTableViewCell
让contact=searchController.isActive?searchResults[indexPath.row]:contacts[indexPath.row]
如果contact.birth==nil{
cell.registeredBday.ishiden=true
}
否则{
cell.registeredBday.ishiden=false
}
cell.namelab.text=“\(contact.givenName)\(contact.familyName)”
// 4
如果contact.imageDataAvailable==true,则让imageData=contact.imageData{
cell.contactImage.image=UIImage(数据:imageData)
}
否则{
cell.contactImage.image=UIImage(名为:“MaLong”)
}
返回单元
}
重写func tableView(tableView:UITableView,willSelectRowAt indexath:indexPath)->indexath{
selectedContactCN=contacts[indexPath.row]
返回索引XPath
}
}
我希望你能给我一个解决方案。
谢谢大家

。因为谓词无效=)。更新代码如下:

func filterResultsWithSearchString(searchString:String){
让KeyFetch=[CNContactGivenNameKey作为CNKeyDescriptor,CNContactFamilyNameKey作为CNKeyDescriptor,CNContactImageDataAvailableKey作为CNKeyDescriptor,CNContactBirthdayKey作为CNKeyDescriptor,CNContactImageDataKey作为CNKeyDescriptor,CNContactPhoneNumbersKey作为CNKeyDescriptor]
变量谓词:NSPredicate!
如果searchString.isEmpty{
让containerId=CNContactStore().d
import ContactsUI

let contactPicker = CNContactPickerViewController()
contactPicker.delegate = self
present(contactPicker, animated: true, completion: nil)
extension YourViewController : CNContactPickerDelegate {
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {

    }
    func contactPickerDidCancel(_ picker: CNContactPickerViewController) {

    }
}