ios core-data nspredicate nsfetchrequest

ios - nspredicate swift 4



iOS CoreData NSPredicate para consultar mĂșltiples propiedades a la vez (8)

Además de la respuesta de @Mathias, también puede usar NSCompoundPredicate para sus operaciones AND de esta manera.

Obj-c - y

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"]; NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"]; NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[predicate1, predicate2]];

Swift - Y

let predicate1:NSPredicate = NSPredicate(format: "X == 1") let predicate2:NSPredicate = NSPredicate(format: "Y == 2") let predicate:NSPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2] )

Swift 3 - Y

let predicate1 = NSPredicate(format: "X == 1") let predicate2 = NSPredicate(format: "Y == 2") let predicateCompound = NSCompoundPredicate(type: .and, subpredicates: [predicate1,predicate2])

Estoy tratando de usar una UISearchBar para consultar múltiples propiedades de un objeto NSManagedObject Tengo un objeto NSManagedObject llamado Person , cada persona tiene un name y socialSecurity propiedad socialSecurity . En este momento, mi código puede realizar una búsqueda (búsqueda) de una de esas propiedades o de la otra, pero no ambas al mismo tiempo.

- (void) performFetch { [NSFetchedResultsController deleteCacheWithName:@"Master"]; // Init a fetch request NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"MainObject" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; // Apply an ascending sort for the color items //NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Term" ascending:YES selector:nil]; NSSortDescriptor *sortDescriptor; sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES selector:@selector(caseInsensitiveCompare:)]; NSArray *descriptors = [NSArray arrayWithObject:sortDescriptor]; [fetchRequest setSortDescriptors:descriptors]; // Recover query NSString *query = self.searchDisplayController.searchBar.text; //if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"Term contains[cd] %@", query]; if(searchValue==1) { if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query]; } else { if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"socialSecurity contains[cd] %@", query]; } // Init the fetched results controller NSError *error; self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"pLLetter" cacheName:nil]; self.fetchedResultsController.delegate = self; if (![[self fetchedResultsController] performFetch:&error]) NSLog(@"Error: %@", [error localizedDescription]); [self.tableView reloadData]; }

No sé cómo poner ambas propiedades en esta declaración ...

if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query];

Alguna ayuda o ideas serían muy apreciadas.


Esto puede ser útil si desea buscar múltiples propiedades para cualquier cosa que coincida (por ejemplo, UISearchControllerDelegate):

NSString *searchFor = @"foo"; NSArray *fields = @[@"Surname", @"FirstName", @"AKA", @"Nickname"]; // OR''d dictionary fields to search NSMutableArray *predicates = NSMutableArray.new; for (NSString *field in fields) { [predicates addObject:[NSPredicate predicateWithFormat:@"(%K BEGINSWITH[cd] %@)", field, searchFor]]; } NSPredicate *search = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];

Luego, podría usar esto, por ejemplo, para filtrar una serie de diccionarios:

NSArray *results = [bigArray filteredArrayUsingPredicate:search];

(BEGINSWITH [cd] no es mágico, solo significa que coincidirá con los principios de las cadenas y no distingue entre mayúsculas y minúsculas. Cambie según sea necesario para sus criterios de coincidencia.)


Fraser Hess en CISMGF.com tiene un gran ejemplo de búsqueda. Puede leer la publicación en http://www.cimgf.com/2008/11/25/adding-itunes-style-search-to-your-core-data-application/

Mi código basado en la publicación es:

NSArray *searchTerms = [searchText componentsSeparatedByString:@" "]; if ([searchTerms count] == 1) { // Search in name and description NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(name contains[cd] %@) OR (desc contains[cd] %@)", searchText, searchText]; [self.searchFetchedResultsController.fetchRequest setPredicate:predicate]; } else { // Search in name and description for multiple words NSMutableArray *subPredicates = [[NSMutableArray alloc] init]; for (NSString *term in searchTerms) { NSPredicate *pred = [NSPredicate predicateWithFormat:@"(name contains[cd] %@) OR (desc contains[cd] %@)", term, term]; [subPredicates addObject:pred]; } NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates]; [self.searchFetchedResultsController.fetchRequest setPredicate:predicate]; }


Para Swift:

var predicate = NSCompoundPredicate( type: .AndPredicateType, subpredicates: [predicate1, predicate2] )


Para evitar la advertencia Los tipos de punteros incompatibles que inicializan ''NSCompoundPredicate * _strong'' con una expresión de tipo ''NSPredicate *'' , reemplazan lo siguiente:

NSCompoundPredicate * predicate = [NSCompoundPredicate orPredicateWithSubPredicates:subPredicates];

con este:

NSPredicate * predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];

Fuente: NSCompoundPredicate


Podría usar un NSCompoundPredicate .

Me gusta esto:

NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query]; NSPredicate *predicateSSID = [NSPredicate predicateWithFormat:@"socialSecurity contains[cd] %@", query]; NSArray *subPredicates = [NSArray arrayWithObjects:predicateName, predicateSSID, nil]; NSPredicate *orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates]; request.predicate = orPredicate;

hay un NSCompoundPredicate para AND también: andPredicateWithSubpredicates:


Puede agregar varios términos de búsqueda en un NSPredicate utilizando los operandos booleanos habituales, como AND / OR.

Algo como esto debería hacer el truco.

[NSPredicate predicateWithFormat:@"name contains[cd] %@ OR ssid contains[cd] %@", query, query];

Espero que ayude :)


Solución completa para Swift2

let request = NSFetchRequest(entityName: "Location") let subPredicate1 = NSPredicate(format: "(name = %@)", searchString) let subPredicate2 = NSPredicate(format: "(street = %@)", searchString) let subPredicate3 = NSPredicate(format: "(city = %@)", searchString) request.predicate = NSCompoundPredicate(type: .OrPredicateType, subpredicates: [subPredicate1, subPredicate2, subPredicate3])