NSStringEncoding と文字列とを相互に変換する

Cocoa/Swift プログラミング

Cocoa フレームワークでエンコードの種類を扱うときは NSStringEncoding を使いますが、Web では一般に文字列でエンコードの種類を扱います。

それらを相互に変換する方法を調べてみました。


Cocoa フレームワークでエンコードの種類を扱うときはNSStringEncoding を使って文字セットを表します。

この型はUInt型 で定義されていて、たとえばNSUTF8StringEncoding なら 4 というように定義されていますが、Web などでは "utf-8" のように文字列で扱われることが多いです。

Cocoa フレームワークでは、Core Foundation の機能として、NSStringEncoding の値と"utf-8" のような文字列とを相互に変換する機能が用意されています。

文字セットの表現方法

NSStringEncoding に用意されている文字セット

NSSStringEncoding には、文字セットとして定数が用意されています。

たくさんあるので良く目にするのをピックアップすると、次のようなものがあります。これらがUInt型 型の値で定義されていて、それを使って文字セットの種類を表現できるようになっています。

定数名 文字セット
NSASCIIStringEncoding ASCII 文字セット (7bit)
NSShiftJISStringEncoding Shift-JIS ベースの文字セット (Windows)
NSJapaneseEUCStringEncoding EUC-JP 文字セット
NSISO2022JPStringEncoding JIS 文字セット
NSUTF8StringEncoding UTF8 文字セット
NSUnicodeStringEncoding Unicode 文字セット
NSISOLatin1StringEncoding ISO Latin-1 文字セット

文字列による文字セット

文字列による文字セットの表現としては "utf-8""euc-jp" といったものがあります。

Core Foundation が扱うのはIANA charset で定められている文字列のようで、これについてはCharacter Sets で定義されているみたいです。

ただ、Shift JIS 文字セットについては少し注意が必要そうなので、まずはそれについて記しておくことにします。

Shift JIS 文字セットについて

UTF-8 文字セットが普及する前に有名だった文字セットの一つに、Windows で一般的なShift JIS というものがあります。

これに該当する文字セットが、IANA charset では"shift_jis" らしいのですが、これがNSStringEncodingNSShiftJISEncoding とは別の文字セットを表現している様子です。

具体的には、NSShiftJISEncoding"cp932" 文字セットを表しています。これはいわゆる「Windows 標準の日本語文字セット」で、Shift_JIS をベースにした、別の文字セットとして扱われます。


では、IANA charset で言う"shift_jis" を表すNSSStringEncoding は何かというと、どうやら定義されていない様子でした。

ただし、Core Foundation のCFStringEncoding にはちゃんとkCFStringEncodingShiftJIS として登録されています。

この辺りを整理すると、次のようになっている様子でした。

IANACharSetName IANA charset NSStringEncoding CFStringEncoding
"shiftjis" "shiftjis" (0x80000A01) kCFStringEncodingShiftJIS (0xA01)
"shift-jis" "cp932" NSShiftJISStringEncoding (0x08) kCFStringEncodingDOSJapanese (0x420)

Web での正式なShift JIS の名称は"shift_jis" になるはずなので、それを明確に扱う必要がある場合にはkCFStringEncodingShiftJIS を使うようにする必要がありそうです。ただしSwift言語 では利用できないようなので、その場合は直接0xA01 を使うことになりそうです。

IANA 文字セット文字列をNSStringEncoding に変換する

IANA 文字セット文字列をNSStringEncoding に変換するには、IANA 文字セット文字列をいったんCore Foundation のCFStringEncoding に変換して、それをNSStringEncoding に変換する必要があります。

IANA 文字セット文字列をCFStringEncoding に変換する

IANA 文字セット文字列をCFStringEncoding に変換するには、CFStringConvertIANACharSetNameToEncoding関数 を使用します。

let cfEncoding = CFStringConvertIANACharSetNameToEncoding("utf-8")

たとえばこのようにすることで、IANA 文字セット文字列の"utf-8" から、それを表すCFStringBuiltInEncodings.UTF8.rawValue が得られます。

Objective-C言語 の場合はkCFStringEncodingUTF8 が得られます。

該当する文字セット値が見つからない場合はkCFStringEncodingInvalidId という定数が得られます。

CFStringEncodingNSStringEncoding に変換する

CFStringEncodingNSStringEncoding に変換するには、CFStringConvertEncodingToNSStringEncoding関数 を使用します。

let nsEncoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding)

こうすることで、CFStringEncoding で表現された文字セットをNSStringEncoding に変換できます。

該当する文字セット値が見つからない場合はkCFStringEncodingInvalidId という定数が示す値が得られます。この定数はUint32型 ですが、この関数ではUInt型 として値を返すので、Swift言語 で判定する場合は型の違いに注意が必要です。

NSStringEncoding を IANA 文字セット文字列に変換する

NSStringEncoding を IANA 文字セット文字列に変換したいときには、逆の流れで、NSStringEncoding をいったんCFStringEncoding に変換して、それを IANA 文字セット文字列に変換する必要があります。

NSStringEncodingCFStringEncoding に変換する

NSStringEncodingCFStringEncoding に変換するには、CFStringConvertNSStringEncodingToEncoding関数 を使用します。

let cfEncoding = CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)

たとえばこのようにすることで、UTF8 文字セットを意味するNSUTF8StringEncoding から、それを表すCFStringBuiltInEncodings.UTF8.rawValue が得られます。

Objective-C言語 の場合はkCFStringEncodingUTF8 が得られます。

該当する文字セット値が見つからない場合はkCFStringEncodingInvalidId という定数が得られます。

CFStringEncoding を IANA 文字セット文字列に変換する

CFStringEncoding を IANA 文字セット文字列に変換するには、CFStringConvertEncodingToIANACharSetName関数 を使用します。

let charset = CFStringConvertEncodingToIANACharSetName(cfEncoding)

こうすることで、CFStringEncoding で表現された文字セットを IANA 文字セット文字列に変換できます。

該当する文字セット値が見つからない場合はnil が得られます。