【问题标题】:iOS Swift - Use predicate core data to filter a tableViewiOS Swift - 使用谓词核心数据过滤 tableView
【发布时间】:2017-01-19 16:43:02
【问题描述】:

当我在 tableView 中搜索时,我试图过滤我的 NSFetchedResultsController 对象。我已尝试使用 NSPredicate,但无法使其正常工作。
我使用的是 Swift 3。
这是我的代码:

func filtrarContenido(searchText: String) {
    let buscar = searchText.lowercased()

    let nombrePredicate = NSPredicate(format: "nombre_comercial contains[cd] %@", buscar)
    let razSocialPredicate = NSPredicate(format: "razon_social contains[cd] %@", buscar)
    let predicate = NSCompoundPredicate(type: NSCompoundPredicate.LogicalType.or, subpredicates: [nombrePredicate, razSocialPredicate])

    let respuesta = self.funcCoreData.obtenerResultadosFiltrados(entidad: "Clientes", orden: "nombre_comercial", ascendente: true, predicate: predicate)
    self.resultadosFiltrados = respuesta[1] as! NSFetchedResultsController<NSManagedObject>

    do {
        try self.resultadosFiltrados.performFetch()
    } catch {
        print("???? \(error)")
    }
}

这里是 FuncCoreData 文件中的函数,它返回一个包含NSManagedObjectNSFetchedResultsController 的数组:

func obtenerResultadosFiltrados(entidad: String, orden: String, ascendente: Bool, predicate: NSPredicate) -> [AnyObject] {
    let appDelegate = UIApplication.shared.delegate as? AppDelegate
    let context = appDelegate?.persistentContainer.viewContext

    let objeto = NSFetchRequest<NSManagedObject>(entityName: entidad)
    let ordenacion = NSSortDescriptor(key: orden, ascending: ascendente)
    objeto.sortDescriptors = [ordenacion]
    objeto.predicate = predicate

    print("OBJETO: ", objeto)

    let recorrerResultados = NSFetchedResultsController<NSManagedObject>(fetchRequest: objeto, managedObjectContext: context!, sectionNameKeyPath: "seccionLetra", cacheName: nil)

    var array = [AnyObject]()
    array.append(objeto)
    array.append(recorrerResultados)

    return array
}

好吧,没有得到任何错误,但搜索总是返回空,我认为我在谓词中的表达不正确: NSPredicate(format: "razon_social contains[cd] %@", buscar)
此外,我想让它不敏感,这是通过ANY razon_social .. 实现的?

【问题讨论】:

    标签: swift uitableview core-data filter predicate


    【解决方案1】:

    您的谓词对我来说似乎有效。 “c”表示不区分大小写,“d”表示重音之类的东西。

    我尝试建立一个与您类似的项目,其中包含一个名为 Clientes 的实体,其中包含 3 个可选字符串,分别称为 nombre_comercial、razon_social 和 seccionLetra,使用了您的函数,它似乎正在工作。

    我已尝试在您的 performFetch() 之后立即打印结果并得到正确的结果。

    do {
        try resultadosFiltrados.performFetch()
        if let results = resultadosFiltrados.fetchedObjects as? [Clientes] {
            print ("results.count \(results.count)")
            for cliente in results {
                print("nombre comercial \(cliente.nombre_comercial! )")
            }
         }            
    } catch {
        print("? \(error)")
    }
    

    您应该尝试检查您的数据是否正确,例如通过删除谓词来查看完整的结果等等。

    【讨论】:

      【解决方案2】:

      几天前我得到了一些帮助,我将与您分享。

      var estaBuscando = false
      let funcCoreData = FuncCoreData()
      var resultados: NSFetchedResultsController<NSManagedObject> = NSFetchedResultsController()
      var resultadosFiltrados: NSFetchedResultsController<NSManagedObject> = NSFetchedResultsController()
      var objeto: NSFetchRequest<NSManagedObject> = NSFetchRequest()
      var aFiltrados = [Cliente]()
      
      override func viewWillAppear(_ animated: Bool) {
          super.viewWillAppear(animated)
      
          let respuesta = self.funcCoreData.obtenerResultados(entidad: "Clientes", orden: "nombre_comercial", ascendente: true)
          self.objeto = respuesta[0] as! NSFetchRequest<NSManagedObject>
          self.resultados = respuesta[1] as! NSFetchedResultsController<NSManagedObject>
          do {
              try self.resultados.performFetch()
              self.pintarSecciones()
          } catch {
              print("???? \(error)")
          }
      }
      
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
      
          if estaBuscando {
              let obj2 = self.aFiltrados[indexPath.item]
              cell.codigo.text = obj2.codigo
              cell.titulo.text = obj2.nombre
              cell.subtitulo.text = obj2.razonSocial
              return cell;
          } else {
              if let obj = self.resultados.object(at: indexPath) as? Clientes {
                  cell.codigo.text = obj.codigo!
                  cell.titulo.text = obj.nombre_comercial!
                  cell.subtitulo.text = obj.razon_social!
              }
          }
          return cell
      }
      
      func filtrarContenido(searchText: String) {
          let buscar = searchText.lowercased()
      
          let p1 = NSPredicate(format: "nombre_comercial contains[cd] %@", buscar)
          let p2 = NSPredicate(format: "razon_social contains[cd] %@", buscar)
          let predicate = NSCompoundPredicate(type: NSCompoundPredicate.LogicalType.or, subpredicates: [p1, p2])
          let respuesta = self.funcCoreData.obtenerResultadosFiltrados(entidad: "Clientes", orden: "nombre_comercial", ascendente: true, predicate: predicate)
          self.resultadosFiltrados = respuesta[1] as! NSFetchedResultsController<NSManagedObject>
      
          do {
              try self.resultadosFiltrados.performFetch()
              self.aFiltrados = [Cliente]() // limpiar listado
              // convertir cada resultado obtenido al modelo Cliente
              for cli in self.resultadosFiltrados.fetchedObjects as! [Clientes] {
                  let cliente = Cliente()
                  cliente.convertir(cliente: cli)
                  self.aFiltrados.append(cliente)
              }
          } catch {
              print("???? Filtrar clientes \(error)")
          }
      }
      
      func searchDisplayController(_ controller: UISearchDisplayController, shouldReloadTableForSearch searchString: String?) -> Bool {
          self.filtrarContenido(searchText: searchString!)
          return true
      }
      
      func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
          if(searchText.isEmpty) {
              estaBuscando = false
          } else {
              estaBuscando = true
          }
          self.filtrarContenido(searchText: searchText)
          self.tableView.reloadData()
      }
      

      文件:FuncCoreData.swift

      func obtenerResultadosFiltrados(entidad: String, orden: String, ascendente: Bool, predicate: NSPredicate) -> [AnyObject] {
          let appDelegate = UIApplication.shared.delegate as? AppDelegate
          let context = appDelegate?.persistentContainer.viewContext
          let objeto = recorrerObjeto(entidad: entidad, orden: orden, ascendente: ascendente)
          objeto.predicate = predicate
          let recorrerResultados = NSFetchedResultsController<NSManagedObject>(fetchRequest: objeto, managedObjectContext: context!, sectionNameKeyPath: "seccionLetra", cacheName: nil)
      
          var array = [AnyObject]()
          array.append(objeto)
          array.append(recorrerResultados)
      
          return array
      }
      
      func obtenerResultados(entidad: String, orden: String, ascendente: Bool) -> [AnyObject] {
          let appDelegate = UIApplication.shared.delegate as? AppDelegate
          let context = appDelegate?.persistentContainer.viewContext
          let objeto = recorrerObjeto(entidad: entidad, orden: orden, ascendente: ascendente)
          let recorrerResultados = NSFetchedResultsController<NSManagedObject>(fetchRequest: objeto, managedObjectContext: context!, sectionNameKeyPath: "seccionLetra", cacheName: nil)
      
          var array = [AnyObject]()
          array.append(objeto)
          array.append(recorrerResultados)
      
          return array
      }
      
      func recorrerObjeto(entidad: String, orden: String, ascendente: Bool) -> NSFetchRequest<NSManagedObject> {
          let objeto = NSFetchRequest<NSManagedObject>(entityName: entidad)
          let ordenacion = NSSortDescriptor(key: orden, ascending: ascendente, selector: #selector(NSString.caseInsensitiveCompare))
          objeto.sortDescriptors = [ordenacion]
          return objeto
      }
      

      文件:Clientes+CoreDataProperties.swift

      import Foundation
      import CoreData
      extension Clientes {
      
          @nonobjc public class func fetchRequest() -> NSFetchRequest<Clientes> {
              return NSFetchRequest<Clientes>(entityName: "Clientes");
          }
      
          @NSManaged public var cif_dni: String?
          @NSManaged public var codigo: String?
          @NSManaged public var domicilio: String?
          ...
      
          var seccionLetra: String? {
              let letra = nombre_comercial!.characters.map { String($0) }
              return letra[0].uppercased()
          }
      }
      

      重要!!文件:Cliente.swift。
      具有函数“convertir()”的对象类“Cliente”。 这个类就像一个填充了'aFiltrados'的对象,过滤一个CoreData对象需要将它转换成这个对象'Cliente'。

      import UIKit
      
      class Cliente {
          var codigo = ""
          var nombre = ""
          ...
          ...
      
          func convertir(cliente: Clientes) {
              codigo = cliente.cif_dni!
              nombre = cliente.nombre_comercial!
              ...
              ...
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2017-09-12
        • 1970-01-01
        • 2013-05-21
        • 2017-07-27
        • 2017-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多