views:

3551

answers:

4

I am currently trying to put together an URL where I specify some GET parameters. But I want to use japanese or other characters too in this URL.

Is there a way to convert a NSString to a string containing the HTML entities for the 'special' characters in my NSString?

I am currently using the following code, which seems to work, except for 'special characters' like chinese and japanese:

NSString* url = @"/translate_a/t?client=t&sl=auto&tl=";
url = [url stringByAppendingString:destinationLanguage];
url = [url stringByAppendingString:@"&text="];
url = [url stringByAppendingString:text];

NSURL* nsurl = [[NSURL alloc] initWithScheme:@"http" host:@"translate.google.com" path:url]; 

NSError* error;
NSString* returnValue = [[NSString alloc] initWithContentsOfURL:nsurl encoding:NSUTF8StringEncoding error:&error];
+1  A: 

NSString has a method -stringByAddingPercentEscapesUsingEncoding:

Graham Lee
+1  A: 

Here's NSString extension you can find over internet

http://code.google.com/p/wimframework/source/browse/trunk/WimFramework/Classes/Helpers/WimAdditions.m

The decode part has some error in mapping array index to actual entity number. But since you only need encoding, it's fine to use it.

digdog
+2  A: 

To properly URL encode your parameters, you need to convert each name and value to UTF-8, then URL encode each name and value separately, then join names with values using '=' and name-value pairs using '&'.

I generally find it easier to put all the parameters in an NSDictionary, then build the query string from the dictionary. Here's a category that I use for doing that:

// file NSDictionary+UrlEncoding.h
#import <Cocoa/Cocoa.h>

@interface NSDictionary (UrlEncoding)

-(NSString*) urlEncodedString;

@end


// file NSDictionary+UrlEncoding.m
#import "NSDictionary+UrlEncoding.h"

// private helper function to convert any object to its string representation
static NSString *toString(id object) {
  return [NSString stringWithFormat: @"%@", object];
}

// private helper function to convert string to UTF-8 and URL encode it
static NSString *urlEncode(id object) {
  NSString *string = toString(object);
  return [string stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
}


@implementation NSDictionary (UrlEncoding)

-(NSString*) urlEncodedString {
  NSMutableArray *parts = [NSMutableArray array];
  for (id key in self) {
    id value = [self objectForKey: key];
    NSString *part = [NSString stringWithFormat: @"%@=%@", 
                     urlEncode(key), urlEncode(value)];
    [parts addObject: part];
  }
  return [parts componentsJoinedByString: @"&"];
}

@end

The method build an array of name-value pairs called parts by URL encoding each key and value, then joining them together with '='. Then the parts in the parts array are joined together with '&' characters.

So for your example:

#import "NSDictionary+UrlEncoding.h"
// ...
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters setValue: @"t" forKey: @"client"];
[parameters setValue: @"auto" forKey: @"sl"];
[parameters setValue: destinationLanguage forKey: @"tl"];
[parameters setValue: text forKey: @"text"];
NSString *urlString = [@"/translate_a/t?" stringByAppendingString: [parameters urlEncodedString]];
Don McCaughey
This is great. Thanks.
Michael Grinich
A: 

For simple URL encoding of strings, many of the solutions I have seen, while technically correct, look a lot less easy to use than I would like. So I came up with the following NSString category:

@interface NSString (MLExtensions)

- (NSString *)urlencode;

@end


NSString *_mlfilterChars = @";/?:@&=+$,";

@implementation NSString (MLExtensions)

- (NSString *)urlencode
{
    return [[NSString stringWithString: (NSString *)
        CFURLCreateStringByAddingPercentEscapes(
            NULL, 
            (CFStringRef)self,
            NULL, 
            (CFStringRef)_mlfilterChars,
            kCFStringEncodingUTF8)]
               stringByReplacingOccurrencesOfString: @"%20" withString: @"+"];
}

@end

I'm kind of in a hurry with some other stuff I'm working on, so I kind of cheated with the %20 => + conversion step, but it all seems to work great and I've been using it for a while now with a good number of URLs in my app.

Usage is blessfully easy:

- (NSString *)URLForSearch: (NSString *)searchFor
{
    return [@"http://example.org/search?query="
                   stringByAppendingString: [searchFor urlencode]];
}