104
103

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOS7でのURL encode/decode

Last updated at Posted at 2014-01-22

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対応は外せないのでしばらくは共存になりますね。残念です。。。

104
103
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
104
103

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?