itok's Lab

昔の開発ネタを記録として残してます

CocoaでいわゆるURI encode

Cocoaといいつつ、実はCoreFoundationにしかメソッドがなかったりしますけれど、いわゆるところのURI encode/decode(%エスケープ)を行う方法。encode はこう。

// 通常文字列 → %エスケープ (encode)
CFStringRef CFURLCreateStringByAddingPercentEscapes(
    CFAllocatorRef allocator,                    // アロケーター(普通は kCFAllocatorDefault)
    CFStringRef originalString,                  // もとの文字列
    CFStringRef charactersToLeaveUnescaped,      // %エスケープして欲しくないもの(NULL で全部エスケープ)
    CFStringRef legalURLCharactersToBeEscaped,   // %エスケープしたいもの(NULL で全部エスケープ)
    CFStringEncoding encoding                    // エンコーディング(普通は kCFStringEncodingUTF8)
);

ただ、これだともともとの文字列が%エスケープを含んでいた場合に危険なので、Appleのドキュメントでは decode との併用を推奨。

// %エスケープ → 通常文字列 (decode)
CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding(
    CFAllocatorRef allocator,                // アロケーター(普通は kCFAllocatorDefault)
    CFStringRef originalString,              // もとの文字列
    CFStringRef charactersToLeaveEscaped,    // %エスケープのままにして欲しい(置き換えたくない)もの
                                             // (NULL で全部置き換えなし、CFSTR("") で全部置き換え)
    CFStringEncoding encoding                // エンコーディング(普通は kCFStringEncodingUTF8)
);

で、例えばこんな感じ。

// %エスケープ → 通常文字列 (encode)
CFStringRef tmp = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(
    kCFAllocatorDefault,
    originalStr,
    CFSTR(""),
    kCFStringEncodingUTF8);

// 通常文字列 → %エスケープ (decode)
CFStringRef escapedStr = CFURLCreateStringByAddingPercentEscapes(
    kCFAllocatorDefault,
    tmp,
    nil,
    nil,
    kCFStringEncodingUTF8);

あとは適当に NSString にキャストしたりすればCocoaでも使えるってことで。