日本語だからこそつきまとう文字エンコード問題にまたつまづきました。 NSURLConnectionでダウンロードしたファイルの文字エンコードがわからず、文字化け・・・・。 htmlの中荷は買いてあるんだけど、それを見るためには一度NSDataからNSStringにしたいけどそこでエンコードがわからないという鶏と卵問題になりかけたので、ちょっとメモっときます。
ヘッダ情報からエンコードを取得する
まず一番楽なのが、このヘッダ情報からエンコードを取得する方法です。 NSURLConnectionのデリゲートでヘッダが帰ってきた時に一緒にエンコード名が取得できます。
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ NSString \*textEncodingName = [response textEncodingName]; }
```objective-c
あとはこれをもとに、エンコードを取得してあげます。
```objective-c
NSString \*encodingName = [textEncodingName lowercaseString]; encodingName = [[encodingName componentsSeparatedByString:@"-"] componentsJoinedByString:@""]; encodingName = [[encodingName componentsSeparatedByString:@"_"] componentsJoinedByString:@""]; NSStringEncoding encoding; if ([encodingName isEqualToString:@"eucjp"]) { encoding = NSJapaneseEUCStringEncoding; } else if ([encodingName isEqualToString:@"shiftjis"] || [encodingName isEqualToString:@"sjis"]) { encoding = NSShiftJISStringEncoding; } else { encoding = NSUTF8StringEncoding; } NSString encodedString = [[[NSString alloc] initWithData:self.downloadedData encoding:encoding] autorelease];
ただ、ちょっと気をつけないといけないことがあって、
- そもそもヘッダにエンコード情報が入っていないことがある
- エンコード名は結構自由に入れられるらしいので、きっちり対応するのは難しい
って問題があります。 でもこれが一番簡単&実行できるときは確実なので、まずこれを試したあと、他の試すのがいいかと思います。
総当りで変換する
とりあえず、NSStringのinitWithData: encoding:はエンコードが間違ってるとnilが帰ってくることを利用して
NSStringEncoding encodes[] = {NSJapaneseEUCStringEncoding, NSShiftJISStringEncoding, NSUTF8StringEncoding}; if(!encodedString){ for (int i = 0; i < 3; i++) { encodedString = [[[NSString alloc] initWithData:self.downloadedData encoding:encodes[i]] autorelease]; if(encodedString){ encoding = encodes[i]; break; } } }
と無理やりやってしまう方法もあります。 ちょっと動作が重そうなのと、特殊文字が入っているとアウトなこと以外は万能そうな方法です。
他にもhtml内部に書かれた文字コードを取得して〜とかあると思いますが、ちょっと難しい&めんどくさかったので普段そんなに使わないだろうということで割愛。 そもそも普通の人はエンコードがわからない状態のものをDLすることってないんですかね??