2017-01-19 13 views
0

tableviewで検索するときにNSFetchedResultsControllerオブジェクトをフィルタリングしようとしています。私はNSPredicateで試してみましたが、動作させることはできません。
私はこれが私のコードであるスウィフト3.
を使用しています:iOS Swift - 述語コアデータを使用してtableViewをフィルタリングする

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 ..で達成されますか?

答えて

0

私は少し前に少しの助けを借りてそれを手に入れました。私はそれをあなたと共有します。

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! 
     ... 
     ... 
    } 
} 
0

あなたの述語は私にとって有効です。 "c"はcaseInsensitive、 "d"はアクセントとそのようなものです。

私はあなたのようなプロジェクトをセットアップしようとしました。クライアントと呼ばれるエンティティで、nombre_comercialという3つのオプションのString(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)") 
} 

データが正しいかどうか、たとえば述語を削除して完全な結果を確認してください。

関連する問題