Skip navigation.
 
mlRe: Percent Encoding Url Components
FROM : Jerry Krinock
DATE : Thu Apr 26 23:25:16 2007

On 2007 Apr, 26, at 13:58, John Cassington wrote:

> Here is my code so far, which has not been working:
>
> - (NSString <http://cocoadev.com/index.pl?NSString>
> *)urlEncodeValue:(NSString <http://cocoadev.com/index.pl?NSString>
> *)string {
>     CFStringRef <http://cocoadev.com/index.pl?CFStringRef>
> originalURLString = (CFStringRef
> <http://cocoadev.com/index.pl?CFStringRef>)string;
>     CFStringRef <http://cocoadev.com/index.pl?CFStringRef>
> preprocessedString =
> CFURLCreateStringByReplacingPercentEscapesUsingEncoding
> (kCFAllocatorDefault,
> originalURLString, CFSTR(""), kCFStringEncodingUTF8);
>     CFStringRef <http://cocoadev.com/index.pl?CFStringRef>  urlString =
> CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
> preprocessedString, NULL, NULL, kCFStringEncodingUTF8);
>     return (NSString <http://cocoadev.com/index.pl?NSString>  *)
> urlString;
> }


Why are there all those <http://....> in that code?  Either it's some 
new syntax that's Way Over My Head, or your email client, or mine 
(Mail.app) is doing something weird?  Maybe either explain or re-post 
without all that weirdness.

> I have also tried the following
>
> - (NSString <http://cocoadev.com/index.pl?NSString>
> *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding
>
> but that method doesn't seem to encode all values, such as ! and + 
> etc.


Probably because this is stringByAddingPercentEscapesUsingEncoding is 
a wrapper for the CF method which, by default, only encodes the 
characters specified by RFC 2396 as needing to be encoded. 
Characters ! and + do not need to be encoded.

Here is part of a category I wrote which might help you out:

@interface  NSString (NSStringBookdogURLHelp)

- (NSString*)encodePercentEscapesPerRFC2396 ;
- (NSString*)encodePercentEscapesStrictlyPerRFC2396 ;
   // Decodes any existing percent escapes which should not be encoded 
per RFC 2396 sec. 2.4.3
   // Encodes any characters which should be encoded per RFC 2396 sec. 
2.4.3.
- (NSString*)encodePercentEscapesPerRFC2396ButNot:(NSString*)butNot 
butAlso:(NSString*)butAlso ;
- (NSString*)decodeAllPercentEscapes ;
   // I did an experiment to find out which ASCII characters are encoded,
   // by encoding a string with all the nonalphanumeric characters 
available on the
   // Macintosh keyboard, with and without the shift key down.  There 
were fourteen:
   //      ` # % ^ [ ] { } \ | " < >
   // You only see thirteen because the fourtheenth one is the space 
character, " ".
   // This agrees with the lists of "space" "delims" and "unwise" in 
by RFC 2396 sec. 2.4.3
   // Also, I found that all of the non-ASCII characters available on 
the Macintosh
   // keyboard by using option or shift+option are also encoded.  Some 
of these have
   // two bytes of unicode to encode, for example %C2%A4 for 0xC2A4

@end

@implementation NSString (NSStringBookdogURLHelp)

- (NSString*)encodePercentEscapesPerRFC2396 {
   return (NSString*)[(NSString*)CFURLCreateStringByAddingPercentEscapes
(NULL, (CFStringRef)self, NULL, NULL, kCFStringEncodingUTF8) 
autorelease] ;
}

- (NSString*)encodePercentEscapesStrictlyPerRFC2396 {
   
   CFStringRef decodedString = (CFStringRef)[self 
decodeAllPercentEscapes] ;
   // The above may return NULL if url contains invalid escape 
sequences like %E8me, %E8fe, %E800 or %E811,
   // because CFURLCreateStringByReplacingPercentEscapes() isn't smart 
enough to ignore them.
   CFStringRef recodedString = CFURLCreateStringByAddingPercentEscapes
(kCFAllocatorDefault, decodedString, NULL, NULL, kCFStringEncodingUTF8);
   // And then, if decodedString is NULL, recodedString will be NULL too.
   // So, we recover from this rare but possible error by returning the 
original self
   // because it's "better than nothing".
   NSString* answer = (recodedString != NULL) ? [(NSString*)
recodedString autorelease] : self ;
   // Note that if recodedString is NULL, we don't need to CFRelease() it.
   // Actually, unlike [nil release], CFRelease(NULL) causes a crash. 
Thanks, Apple!
   return answer ;
}

- (NSString*)encodePercentEscapesPerRFC2396ButNot:(NSString*)butNot 
butAlso:(NSString*)butAlso {
   return (NSString*)[(NSString*)CFURLCreateStringByAddingPercentEscapes
(NULL, (CFStringRef)self, (CFStringRef)butNot, (CFStringRef)butAlso, 
kCFStringEncodingUTF8) autorelease] ;
}

- (NSString*)decodeAllPercentEscapes {
   // Unfortunately, CFURLCreateStringByReplacingPercentEscapes() seems 
to only replace %[NUMBER] escapes
   return (NSString*)[(NSString*)
CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, 
(CFStringRef)self, CFSTR("")) autorelease] ;
}

@end

Related mailsAuthorDate
mlPercent Encoding Url Components John Cassington Apr 26, 22:58
mlRe: Percent Encoding Url Components Jerry Krinock Apr 26, 23:25