iOS Swift - 使用谓词核心数据过滤一个tableView
iOS Swift - Use predicate core data to filter a tableView
我在 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 文件中的函数,它 return 是一个包含 NSManagedObject
和 NSFetchedResultsController
的数组:
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
}
嗯,没有得到任何错误,但搜索总是return空的,我认为我在谓词中的表达不正确:
NSPredicate(format: "razon_social contains[cd] %@", buscar)
此外,我想让它 insensitive,这是通过 ANY razon_social ..
?
实现的
你的谓词对我来说似乎有效。 "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)")
}
您应该尝试检查您的数据是否正确,例如通过删除谓词,查看完整的结果等。
前些日子在大家的帮助下搞定了,分享给大家。
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
}
文件:客户+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([=12=]) }
return letra[0].uppercased()
}
}
重要!! 文件:Cliente.swift.
具有函数 'convertir()' 的对象 class 'Cliente'。
这个 class 就像一个填充了 'aFiltrados' 的对象,要过滤一个 CoreData 对象需要将它转换成这个对象 'Cliente'.
import UIKit
class Cliente {
var codigo = ""
var nombre = ""
...
...
func convertir(cliente: Clientes) {
codigo = cliente.cif_dni!
nombre = cliente.nombre_comercial!
...
...
}
}
我在 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 文件中的函数,它 return 是一个包含 NSManagedObject
和 NSFetchedResultsController
的数组:
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
}
嗯,没有得到任何错误,但搜索总是return空的,我认为我在谓词中的表达不正确:
NSPredicate(format: "razon_social contains[cd] %@", buscar)
此外,我想让它 insensitive,这是通过 ANY razon_social ..
?
你的谓词对我来说似乎有效。 "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)")
}
您应该尝试检查您的数据是否正确,例如通过删除谓词,查看完整的结果等。
前些日子在大家的帮助下搞定了,分享给大家。
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
}
文件:客户+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([=12=]) }
return letra[0].uppercased()
}
}
重要!! 文件:Cliente.swift.
具有函数 'convertir()' 的对象 class 'Cliente'。
这个 class 就像一个填充了 'aFiltrados' 的对象,要过滤一个 CoreData 对象需要将它转换成这个对象 'Cliente'.
import UIKit
class Cliente {
var codigo = ""
var nombre = ""
...
...
func convertir(cliente: Clientes) {
codigo = cliente.cif_dni!
nombre = cliente.nombre_comercial!
...
...
}
}