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])