Problem polega na tym, czy db ma niewrażliwe porównanie na znaki diakrytyczne. Druga kwestia to znaki złożone, ï można wyrazić jako jeden znak unicode lub dwa tworzące parę zastępczą. Istnieją metody konwersji ciągu do postaci wstępnie złożonej lub rozłożonej:precomposedStringWith* i decomposedStringWith*.
Wygląda na to, że MySQL obsługuje dwie formy unikodu ucs2 (jest to starsza forma, która została zastąpiona przez utf16), czyli 16 bitów na znak i utf8 do 3 bajtów na znak. Złą wiadomością jest to, że żaden formularz nie obsługuje znaków płaszczyzny 1, które wymagają 17 bitów. (głównie emoji). Wygląda na to, że MySQL 5.5.3 i nowsze obsługują również utf8mb4, utf16 i utf32 obsługują BMP i znaki uzupełniające (czytaj emoji). Zobacz Zestawy znaków Unicode MySQL .
Oto kod i wyniki, aby zademonstrować różne reprezentacje bajtów Unicode.
Unicode to 21-bitowy system kodowania.
UTF32 bezpośrednio reprezentuje punkty kodowe i wyraźnie demonstruje rozłożone pary zastępcze.
UTF8 i UTF16 wymagają jednego lub więcej bajtów do reprezentowania znaku 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]);
// Dla niektórych par zastępczych nie ma innej formy
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]);
Wyjście 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>