iOS Swift - 使用谓词核心数据筛选表视图



当我在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 .. 实现的?

你的谓词对我来说看起来有效。"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
}

文件:客户端+核心数据属性.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()
    }
}

重要!!文件:客户.swift。
一个对象类 'Cliente',函数 'convertir()'。这个类的工作方式类似于填充"aFiltrados"的对象,并且需要过滤CoreData对象以将其转换为此对象"Cliente"。

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

最新更新