views:

1027

answers:

3

I need to pass a timestamp with a timezone offset in a GET request, e.g.,

2009-05-04T11:22:00+01:00

This looks like a two arguments "2009-05-04T11:22:00" and "01:00" to the receiving PHP script (over which I've no control).

NSURL doesn't encode plus signs, but if I make an NSURL using the string

2009-05-04T11:22:00%2B01:00

the url I end up with contains:

2009-05-04T11:22:00%252B01:00

Any ideas how I can preserve my encoded plus sign or just plain prevent NSURL from encoding anything?

+1  A: 

Use NSString's stringByAddingPercentEscapesUsingEncoding: method on the text you want to include as an argument.

As its name implies, the method will convert return an auto-released string containing an url-safe version of the receiver.

Kenneth Ballenegger
I tried that - it converts '+' to '%2B'. NSURL then encodes the '%' so you end up with '%252B'
edoloughlin
Most probably, you're doing something wrong with the URL then. You need to use NSURL's `URLWithString:`.
Kenneth Ballenegger
And make sure you're not calling that method twice on the same string, otherwise it <em>will</em> call it encode your resulting string twice, thus encoding the % into a %25. Also make sure you're using NSUTF8Encoding everywhere.
Kenneth Ballenegger
It just plain doesn't work. The '+' character is perfectly valid in URLs and won't be encoded by NSURL. If you leave it in, it appears as a separate argument.In the end, I had to convert the timestamp to GMT and remove the timezone offset from the string. Not pretty, but there's other stuff to move on to...
edoloughlin
+1  A: 

Thought I may as well provide my workaround as an answer, as I don't think there's a good solution to the original problem.

The plus sign (+) is completely valid in a URL, so my solution was to convert the time to GMT and remove the timezone/DST offset from the string. I'll leave it as an exercise for the reader to determine the value of secondsFromGMT below as, in my case, it's always the same because I'm only interested in timestamps generated by a web server.

NSString *gmtWhen = [[self descriptionWithCalendarFormat:nil
                           timeZone:[NSTimeZone
                           timeZoneForSecondsFromGMT:secondsFromGMT
                     ] locale:nil] stringByReplacingOccurrencesOfString:@" +0000" withString:@""];
edoloughlin
+1  A: 

What worked for me was doing the UTF8 conversion, then replacing the + sign with %2B:

NSString *urlString =
    [NSString stringWithFormat:@"%@/iphone/push/create?pn[token]=%@&pn[send_at]=%@",
     kHTTPURL, appDelegate.deviceAPNToken, [dateTimeToUse description]];

urlString =
    [[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
     stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];
anonymous