El problema es si la base de datos tiene una comparación insensible diacrítica. El otro problema son los caracteres compuestos, ï se puede expresar como un carácter Unicode o dos que forman un par sustituto. Existen métodos para convertir una cadena en una forma precompuesta o descompuesta:precomposedStringWith* y decomposedStringWith*.
Parece que MySQL admite dos formas de Unicode ucs2 (que es una forma más antigua que fue reemplazada por utf16) que es de 16 bits por carácter y utf8 de hasta 3 bytes por carácter. La mala noticia es que ninguna forma admitirá los caracteres del plano 1 que requieren 17 bits. (principalmente emojis). Parece que MySQL 5.5.3 y versiones posteriores también admiten utf8mb4, utf16 y utf32 admiten BMP y caracteres complementarios (leer emoji). Consulte Conjuntos de caracteres Unicode de MySQL .
Aquí hay algunos códigos y resultados para demostrar las diferentes representaciones de bytes Unicode.
Unicode es un sistema de codificación de 21 bits.
UTF32 representa directamente los puntos de código y demuestra claramente los pares sustitutos descompuestos.
UTF8 y UTF16 requieren uno o más bytes para representar un carácter Unicode.
NSLog(@"character: %@", @"Å");
NSLog(@"decomposedStringWithCanonicalMapping UTF8: %@", [[@"Å" decomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF8StringEncoding]);
NSLog(@"decomposedStringWithCanonicalMapping UTF16: %@", [[@"Å" decomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF16BigEndianStringEncoding]);
NSLog(@"decomposedStringWithCanonicalMapping UTF32: %@", [[@"Å" decomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF32BigEndianStringEncoding]);
NSLog(@"precomposedStringWithCanonicalMapping UTF8: %@", [[@"Å" precomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF8StringEncoding]);
NSLog(@"precomposedStringWithCanonicalMapping UTF16: %@", [[@"Å" precomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF16BigEndianStringEncoding]);
NSLog(@"precomposedStringWithCanonicalMapping UTF32: %@", [[@"Å" precomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF32BigEndianStringEncoding]);
NSLog(@"character: %@", @"😱");
NSLog(@"dataUsingEncoding UTF8: %@", [@"😱" dataUsingEncoding:NSUTF8StringEncoding]);
NSLog(@"dataUsingEncoding UTF16: %@", [@"😱" dataUsingEncoding:NSUTF16BigEndianStringEncoding]);
NSLog(@"dataUsingEncoding UTF32: %@", [@"😱" dataUsingEncoding:NSUTF32BigEndianStringEncoding]);
// Para algunos pares sustitutos no hay otra forma
NSString *aReverse = [[NSString alloc] initWithBytes:"\xD8\x3C\xDD\x70\x00" length:4 encoding:NSUTF16BigEndianStringEncoding];
NSLog(@"character: %@", aReverse);
NSLog(@"dataUsingEncoding UTF8: %@", [aReverse dataUsingEncoding:NSUTF8StringEncoding]);
NSLog(@"dataUsingEncoding UTF16: %@", [aReverse dataUsingEncoding:NSUTF16BigEndianStringEncoding]);
NSLog(@"dataUsingEncoding UTF32: %@", [aReverse dataUsingEncoding:NSUTF32BigEndianStringEncoding]);
Salida de NSLog:
character: Å
decomposedStringWithCanonicalMapping UTF8: <41cc8a>
decomposedStringWithCanonicalMapping UTF16: <0041030a>
decomposedStringWithCanonicalMapping UTF32: <00000041 0000030a>
precomposedStringWithCanonicalMapping UTF8: <c385>
precomposedStringWithCanonicalMapping UTF16: <00c5>
precomposedStringWithCanonicalMapping UTF32: <000000c5>
character: 😱
dataUsingEncoding UTF8: <f09f98b1>
dataUsingEncoding UTF16: <d83dde31>
dataUsingEncoding UTF32: <0001f631>
character: 🅰
dataUsingEncoding UTF8: <f09f85b0>
dataUsingEncoding UTF16: <d83cdd70>
dataUsingEncoding UTF32: <0001f170>