2013-06-04 17 views
5

Ho un mazzo di caratteri unicode avvolto in NSNumber modo:NSString da Unicode

@(0x1f4de), // EntypoIconTypePhone 
@(0x1f4f1), // EntypoIconTypeMobile 
@(0xe789),  // EntypoIconTypeMouse 
@(0xe723),  // EntypoIconTypeAddress 
@(0x2709),  // EntypoIconTypeMail 
@(0x1f53f), // EntypoIconTypePaperPlane 
@(0x270e),  // EntypoIconTypePencil 

Queste sono icone dal carattere Entypo (altamente raccomandato).

Questo è il codice che sto usando per creare NSString dal unicode:

NSNumber *u = self.unicodeLookup[type]; 

int unicode = [u intValue]; 
UniChar chars[] = {unicode}; 

NSString *string = [[NSString alloc] initWithCharacters:chars length:sizeof(chars)/sizeof(UniChar)]; 

Quello che sto trovando è che alcune di queste icone vengono creati come previsto, ma non tutti; e da quello che posso vedere sono gli unicodes che hanno 5 cifre in loro che non vengono creati correttamente.

Per esempio, questi lavori:

@(0xe723),  // EntypoIconTypeAddress 
@(0x2709),  // EntypoIconTypeMail 

ma questi non:

@(0x1f4de), // EntypoIconTypePhone 
@(0x1f4f1), // EntypoIconTypeMobile 

Sono abbastanza sicuro che questo è il mio codice di conversione. Non capisco davvero tutta questa codifica maligna.

+0

+1 per malarkey – uchuugaka

risposta

2

Se si memorizzano i costanti carattere utilizzando unichar, piuttosto che NSNumber oggetti, poi il compilatore stesso vi dirà il motivo:

unichar chars[] = 
{ 
    0xe723,  // EntypoIconTypeAddress 
    0x2709,  // EntypoIconTypeMail 
    0x1f4de, // EntypoIconTypePhone 
    0x1f4f1  // EntypoIconTypeMobile 
}; 

Implicit conversion from 'int' to 'unichar' (aka 'unsigned short') changes value from 128222 to 62686 
Implicit conversion from 'int' to 'unichar' (aka 'unsigned short') changes value from 128241 to 62705 

Come iOS/OSX utilizza la rappresentazione a 16 bit di caratteri Unicode internamente e 0x1f4de e 0x1f4f1 sono entrambi a 32 bit, si sta andando ad avere bisogno di codificare questi caratteri come coppie di surrogati:

a = 0x1f4de - 0x10000 = 0xf4de 
high = a >> 10 = 0x3d 
low = a & 0x3ff = 0xde 
w1 = high + 0xd800 = 0xd83d 
w2 = low + 0xdc00 = 0xdcde 

0x1f4de (UTF-32) = 0xd83d 0xdcde (UTF-16) 

(vai a questa Wikipedia page).

Il risultato è che non è possibile utilizzare una singola matrice di caratteri unicode poiché si dovrà conoscere la lunghezza della codifica di ciascun carattere.

+0

Sono riuscito a visualizzare i caratteri nel tuo esempio utilizzando il codice nel mio secondo commento. L'unico problema ora sono i caratteri di carattere sociale. Grazie per il tuo consiglio però, giocherò in giro per vedere se riesco a far funzionare anche quelli. –

+0

Ho notato gli avvertimenti quando ho usato unichar ma funziona se ho appena lanciato il mio array su int. –

+0

@LeeProbert 'int' sarà sempre almeno a 32 bit, ma' unichar' è sempre a 16 bit. Un'opzione per te sarebbe quella di memorizzare i tuoi caratteri come UTF-32 (in un 'unsigned', non' unichar') e quindi usare '[NSString initWithBytes: length: encoding:]' con una codifica di 'NSUTF32StringEncoding', tuttavia potrebbero essere problemi di endianità da risolvere (non l'ho esaminato). – trojanfoe

2

Se Io lo uso per creare il mio String funziona per i valori Unicode int carattere Entypo:

int unicode = uniChars[type]; 

NSString* s = [[NSString alloc] initWithBytes:&unicode length:sizeof(unicode) encoding:NSUTF32LittleEndianStringEncoding]; 

uniChars è un CArray di int s invece dei NSArray di NSNumber s che ho avuto in precedenza. Non c'è ragione per questo, dovrebbe funzionare con entrambi.

UPDATE:

C'è ancora un problema con alcuni dei numeri Unicode. I caratteri del font Entypo Social non vengono visualizzati. La differenza tra questi e le icone normali è che tutti iniziare con F ed avere 4 caratteri:

0xF300 ,   // EntypoIconSocialTypeGithub, 
0xF301 ,   // EntypoIconSocialTypeCGithub, 
0xF303 ,   // EntypoIconSocialTypeFlickr, 
0xF304 ,   // EntypoIconSocialTypeCFlickr, 

Ho il sospetto che la codifica sarebbe stato diverso.