Help us understand the problem. What is going on with this article?

iOS7でのURL encode/decode

More than 3 years have passed since last update.

iOS7以前は標準でそれっぽいメソッドが用意されてますが、これが意図してない感じで動いてくれます。

使えないパターン
NSString* targetString = @"http://hogehoge.com/?param=!*'();:@&=+$,/?%#[]";

// encode
NSString* encodeString = [targetString 
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

// decode
NSString* decodeString = [encodeString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

// なんか違うよねこれ
NSLog(@"encode %@", encodeString); // http://hogehoge.com/param=!*'();:@&=+$,/?%25%23%5B%5D

だから開発者は皆ブログなどからこれじゃないかという解決策を見つけカテゴリーに実装します。

頑張ったパターン
// カテゴリ追加して独自で頑張る
@interface NSString(Url)
-(NSString*) urlEncode;
-(NSString*) urlDecode;
@end

@implementation NSString(Url)
-(NSString*) urlEncode {
    return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
                                                                                                   kCFAllocatorDefault,
                                                                                                   (__bridge CFStringRef)self,
                                                                                                   NULL,
                                                                                                   (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                                                   kCFStringEncodingUTF8));
}

-(NSString*) urlDecode {
    return (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(
                                                                                                 kCFAllocatorDefault,
                                                                                                 (__bridge CFStringRef)self,
                                                                                                 CFSTR(""),
                                                                                                 kCFStringEncodingUTF8));
}
@end

// 実際に動かしてみる
NSString* targetString = @"http://hogehoge.com/?param=!*'();:@&=+$,/?%#[]";
NSString* encodeString = [targetString urlEncode];
NSString* decodeString = [encodeString urlDecode];

// あら?いい感じ
NSLog(@"encode %@", encodeString); // http%3A%2F%2Fhogehoge.com%2F%3Fparam%3D%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%25%23%5B%5D

まぁこれでいいんですが、iOS7からこのように独自で実装しなくてもいいメソッドが追加されたので
せっかくならそれ使って少しでも楽しようぜってのが今回の内容です。
iOS7からNSStringのカテゴリに

- (NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters
- (NSString *)stringByRemovingPercentEncoding

の2個が追加されてます。
これを使用して上記処理を置き換えてみましょう。

iOS7版
NSString* targetString = @"http://hogehoge.com/?param=!*'();:@&=+$,/?%#[]";
NSString* encodeString = [targetString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
NSString* decodeString = [encodeString stringByRemovingPercentEncoding];

 // あら?カテゴリ実装しなくてもいい感じ
NSLog(@"encode %@", encodeString); // http%3A%2F%2Fhogehoge%2Ecom%2F%3Fparam%3D%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%25%23%5B%5D

とほぼ同じ結果になります。
encodeする文字列をカスタマイズしたい場合は引数で渡してるNSCharacterSetを変更すればいいだけですし
こちらの方が何となくおしゃれな感じがしますね。

ただ、現状iOS6対応は外せないのでしばらくは共存になりますね。残念です。。。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした