2013-04-11 12 views
16

-[NSMutableAttributedString initWithHTML:documentAttributes:] wydaje magiel znaków specjalnych:NSAttributedString initWithHTML niepoprawne kodowanie znaków?

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

która drukuje “Hello†World następnie niektórych poleceń RTF. W mojej aplikacji konwertuję przypisany ciąg do formatu RTF i wyświetlam go w postaci NSTextView, ale tam też są uszkodzone znaki.

Zgodnie z dokumentacją, domyślne kodowanie UTF-8, ale starałem się być jawne, a wynik jest taki sam:

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

Odpowiedz

28

Zastosowanie [html dataUsingEncoding:NSUnicodeStringEncoding] podczas tworzenia NSData i ustaw opcję kodowania dopasowanie kiedy parsowania HTML na nadana w ciąg:

dokumentacja NSCharacterEncodingDocumentAttribute jest nieco mylące:

NSNumber, zawierające int określenie pliku NSStringEncoding dla pliku 012; do czytania i pisania zwykłych plików tekstowych i pisania HTML; domyślnym kodowaniem jest zwykły tekst; domyślna dla HTML to UTF-8.

tak, to kod powinien być:

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

Wielki. Dzięki za to. (y) – Sid

+0

Najpierw powinieneś wypróbować drugą odpowiedź, na wypadek gdyby miała rację co do mojej odpowiedzi działającej tylko przypadkowo. Nie miałem okazji sam tego przetestować. : -X – alltom

+0

Są częściowo w porządku. Jest to ta sama odpowiedź (mniej więcej) i działa.Uczyniłem tę odpowiedź jaśniejszą, ponieważ jest oznaczona jako poprawna. –

10

poprzedniej odpowiedzi tutaj działa, ale głównie przez przypadek.

Wykonanie NSData z NSUnicodeStringEncoding będzie działać, ponieważ stała jest aliasem dla NSUTF16StringEncoding, a UTF-16 jest dość łatwy do zidentyfikowania przez system. Łatwiejszy niż UTF-8, który najwyraźniej został zidentyfikowany jako inny nadzbiór ASCII (wygląda na to, że w twoim przypadku jest to NSWindowsCP1252StringEncoding, prawdopodobnie dlatego, że jest to jedno z niewielu kodowań opartych na ASCII z odwzorowaniami dla 0x8_ i 0x9_).

Ta odpowiedź jest błędna w powołując się na dokumentację NSCharacterEncodingDocumentAttribute, bo „atrybuty” to, co dostajesz się z -initWithHTML. Dlatego jest to NSDictionary **, a nie tylko NSDictionary *. Możesz przekazać wskaźnik do NSDictionary *, a otrzymasz klucze takie jak TopMargin/BottomMargin/LeftMargin/RightMargin, PaperSize, DocumentType, UTI, itd. Wartości, które próbujesz przekazać w przez słownik "atrybutów" są ignorowane.

Musisz użyć "opcji" do przekazania wartości w, a odpowiedni klucz opcji to NSTextEncodingNameDocumentOption, który nie ma udokumentowanej wartości domyślnej. Przesyła on bajty do WebKita w celu analizy, więc jeśli nie określisz kodowania, prawdopodobnie dostaniesz heurystykę kodowania i odgadywania kodowania WebKit.

Aby zagwarantować dopasowanie typów kodowania między NSData i NSAttributedString, co należy zrobić, to coś takiego:

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

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

Spróbuję tego, dziękuję! – alltom

+0

Nie sądzę, że to właśnie sugeruje inna odpowiedź. Po prostu nie był kompletny. –

+0

Właściwie to jest poprawna odpowiedź. Inna odpowiedź naprawdę działa tylko wtedy, gdy '-initWithHTML' przez przypadek wykrywa właściwe kodowanie. Używanie opcji 'options' jest właściwą drogą. Dzięki! – fbitterlich

Powiązane problemy