cocoa - NSPredicate insensible a mayúsculas/minúsculas para cadenas de una matriz?
core-data (4)
Tengo una situación en la que quiero buscar objetos de mi almacén de datos centrales con la clave de usuario, pero quiero que la comparación no distinga entre mayúsculas y minúsculas. El predicado que tengo es este:
username IN $usernames
Luego hago una sustitución variable con una matriz de cadenas que son los nombres de usuario que quiero encontrar. Funciona, pero distingue entre mayúsculas y minúsculas. Me gustaría hacer algo como esto, creo:
username IN[c] $usernames
Lamentablemente, eso no parece funcionar. La comparación de cadenas todavía debe estar sucediendo de una manera sensible a mayúsculas y minúsculas. (No obtengo un error acerca de que sea una consulta no compatible).
¿Hay alguna manera diferente de escribir este predicado para que funcione de la manera que necesito o me estoy perdiendo algo obvio aquí?
Aquí hay otra solución, pero requiere que cambie MOM.
Haz que el nombre de usuario sea una entidad completa. Crea la relación inversa entre el nombre de usuario y lo que sea que sea tu otra entidad.
Ahora para la solicitud de búsqueda, configure la entidad como "Nombre de usuario" y luego ejecute este predicado (suponiendo una propiedad "nombre" y una propiedad "principal"):
[NSPredicate predicateWithFormat:"(name like[c] %@) && (parent == %@)", theUserName, theParentObject]
Esto puede ser excesivo, pero le permitirá ejecutar su búsqueda como lo desee.
El modificador de caso en el operador IN aparentemente se ignora al ejecutar una búsqueda contra el almacén SQLite. (Ha omitido el tipo de tienda de su pregunta).
Recomiendo archivar un error en la documentación para que esta limitación / comportamiento pueda documentarse.
También recomendaría presentar una solicitud de función en el reportero de errores para que esto pueda ser considerado para soporte futuro.
Mientras tanto, tendrá que sacar su solicitud de extracción del modelo de datos y compilarla programáticamente. Puede construir un predicado O predicado compuesto que haga una coincidencia de igualdad insensible a mayúsculas y minúsculas para cada uno de sus valores (y pruebe que cumple con sus necesidades de rendimiento).
Tenga en cuenta que si está soportando objetivos de sistema operativo anteriores a 10.6, el modificador de caso en == no es compatible, en cuyo caso se requerirá otra solución alternativa.
Puede probar algo como ANY $usernames LIKE[c] username
. He hecho algo similar, donde en lugar de la sustitución variable, solo tengo una ruta clave como "nombre.personas", y ese predicado funciona para mí. No estoy seguro si funciona de manera diferente con una variable allí en lugar de una ruta clave, pero vale la pena intentarlo.
Aunque esta pregunta tiene varios años, me encontré con el mismo problema y lo resolví así:
NSArray *values = @[@"FOO", @"bar" ,@"lorem"];
NSString *predicate;
predicate = @"value LIKE[cd] ''";
predicate = [predicate stringByAppendingString:
[values componentsJoinedByString:
@"'' OR value LIKE[cd] ''"]];
predicate = [predicate stringByAppendingString:@"''"];
NSLog(@"%@", predicate);
// Output:
// value LIKE[cd] ''FOO'' OR value LIKE[cd] ''bar'' OR value LIKE[cd] ''lorem''
Esto crea una expresión de predicado estático de la lista de valores. Tal vez sea útil para alguien.
ACTUALIZACIÓN 2:
En realidad, parece que la solución actualizada a continuación no funciona con sqlite y produce un
''NSInvalidArgumentException'',
reason: ''unimplemented SQL generation for predicate : ... (bad LHS)''
Creo que para las comparaciones array / dict / set y IN
solo hay teclas permitidas en el lado izquierdo del operador.
ACTUALIZAR:
Después de algunas investigaciones sobre expresiones y predicados encontré otro enfoque, que parece funcionar bastante bien:
NSPredicate *predicate =
[NSPredicate predicateWithFormat:
@"lowercase(value) IN %@", values];
Utiliza la expresión de función lowercase:
para obtener la representación en minúscula del valor. Todo lo que queda por hacer es garantizar que todas las entradas de values
sean minúsculas y podrá usar expresiones IN
insensibles a mayúsculas y minúsculas.