2013-04-11 11 views
16

-[NSMutableAttributedString initWithHTML:documentAttributes:] sembra storpiare i caratteri speciali:NSAttributoString initWithHTML codifica caratteri errata?

NSString *html = @"“Hello” World"; // notice the smart quotes 
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding]; 
NSMutableAttributedString *as = [[NSMutableAttributedString alloc] initWithHTML:htmlData documentAttributes:nil]; 
NSLog(@"%@", as); 

che stampa “Hello†World seguito da alcuni comandi RTF. Nella mia applicazione, converto la stringa attribuita in RTF e la visualizzo in un NSTextView, ma anche i caratteri sono danneggiati.

Secondo la documentazione, la codifica predefinita è UTF-8, ma ho cercato di essere esplicito e il risultato è lo stesso:

NSDictionary *attributes = @{NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]}; 
NSMutableAttributedString *as = [[NSMutableAttributedString alloc] initWithHTML:htmlData documentAttributes:&attributes]; 

risposta

28

Usa [html dataUsingEncoding:NSUnicodeStringEncoding] durante la creazione del NSData e impostare l'opzione di codifica di corrispondenza quando si analizzare il codice HTML in una stringa attribuito:

la documentazione per NSCharacterEncodingDocumentAttribute è un po 'confusa:

NSNumber, contenente un int che specifica il NSStringEncoding per il file ; per leggere e scrivere file di testo semplice e scrivere HTML; predefinito per il testo normale è la codifica predefinita; l'impostazione predefinita per HTML è UTF-8.

Così, il codice dovrebbe essere:

NSString *html = @"“Hello” World"; 
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding]; 
NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, 
            NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}; 
NSMutableAttributedString *as = 
    [[NSMutableAttributedString alloc] initWithHTML:htmlData 
              options: options 
           documentAttributes:nil]; 
+0

Grande. Grazie per questo. (y) – Sid

+0

Dovresti provare prima l'altra risposta nel caso in cui abbiano ragione riguardo alla mia risposta che funziona solo accidentalmente. Non ho avuto la possibilità di testarlo da solo. : -X – alltom

+0

Hanno parzialmente ragione. Questa è la stessa risposta (più o meno) e funziona.Ho reso questa risposta più chiara poiché è contrassegnata come corretta. –

10

La risposta precedente qui funziona, ma soprattutto per caso.

Fare un NSData con NSUnicodeStringEncoding tenderà a funzionare, perché quella costante è un alias per NSUTF16StringEncoding e UTF-16 è piuttosto facile da identificare per il sistema. Più semplice di UTF-8, che a quanto pare veniva identificato come un altro superset di ASCII (sembra il NSWindowsCP1252StringEncoding nel tuo caso, probabilmente perché è una delle poche codifiche basate su ASCII con mapping per 0x8_ e 0x9_).

La risposta è sbagliato nel citare la documentazione per NSCharacterEncodingDocumentAttribute, perché "attributi" sei quello che si ottiene fuori di -initWithHTML. Ecco perché è NSDictionary ** e non solo NSDictionary *. Puoi passare un puntatore a NSDictionary * e otterrai chiavi come TopMargin/BottomMargin/LeftMargin/RightMargin, PaperSize, DocumentType, UTI, ecc. Tutti i valori che cerchi di passare in attraverso il dizionario "attributi" sono ignorato.

È necessario utilizzare "opzioni" per il passaggio dei valori in e la chiave di opzione pertinente è NSTextEncodingNameDocumentOption, che non ha valore predefinito documentato. Passa i byte a WebKit per l'analisi, quindi se non specifichi una codifica, presumibilmente otterrai l'euristica che indovina la codifica di WebKit.

Per garantire la corrispondenza tipi di codifica tra il NSData e NSAttributedString, cosa si dovrebbe fare è qualcosa di simile:

NSString *html = @"“Hello” World"; 
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding]; 

NSMutableAttributedString *as = 
    [[NSMutableAttributedString alloc] initWithHTML:htmlData 
              options:@{NSTextEncodingNameDocumentOption: @"UTF-8"} 
           documentAttributes:nil]; 
+0

Proverò questo, grazie! – alltom

+0

Non penso che sia quello che l'altra risposta stava suggerendo. Semplicemente non era completo. –

+0

In realtà, questa è la risposta corretta. L'altra risposta funziona davvero solo se '-initWithHTML' rileva casualmente la giusta codifica. Usare le 'opzioni' è la strada giusta da percorrere. Grazie! – fbitterlich