401 response Twitter reverse auth - twitter-oauth

Here is the authorization header I use:
Authorization = "OAuth oauth_consumer_key=\"2D9rLD8Lu23hrchrh4VMBkQ6AZKHYi2yY2oeuoeutcFMdAs\", oauth_nonce=\"-486353546\", oauth_signature="x3NdGnJmBTUAICBRE9C44N8mFd4%3D", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"137663828056\", oauth_version=\"1.0\", x_auth_mode=\"reverse_auth\"";
Here's the base string I use:
https://api.twitter.com/oauth/access_token
Here's the twitter documentation I'm working from:
Step 1: Obtain a Special Request Token
First, you make an HTTPS request to the Twitter Request Token URL
https://api.twitter.com/oauth/request_token with your application's
consumer key. In addition to the conventional oauth_* signing
parameters, you must also include x_auth_mode set to the value
reverse_auth.
As an example, consider a request with the following values signed
with the token secret ydC2yUbFaScbSlykO0PmrMjXFeLraSi3Q2HfTOlGxQM:
The tokens used here are for demonstration purposes only, and will not
work for you.
oauth_consumer_key JP3PyvG67rXRsnayOJOcQ oauth_nonce
1B7D865D-9E15-4ADD-8165-EF90D7A7D3D2 oauth_signature_method HMAC-SHA1
oauth_timestamp 1322697052 oauth_version 1.0 x_auth_mode reverse_auth
These parameters should result in a signature base string that looks
like this:
POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_consumer_key%3DJP3PyvG67rXRsnayOJOcQ%26oauth_nonce%3D1B7D865D-9E15-4ADD-8165-EF90D7A7D3D2%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1322697052%26oauth_version%3D1.0%26x_auth_mode%3Dreverse_auth
This call should result in a response that looks like this. Notice
that this response actually looks like an OAuth header.
(line wrapping added for clarity):
OAuth oauth_nonce="xq2maKtilFhVTC1MSxVC4cQIJLd53O6w97YmrdOGSk8",
oauth_signature_method="HMAC-SHA1", oauth_timestamp="1322697052",
oauth_consumer_key="JP3PyvG67rXRsnayOJOcQ",
oauth_token="5mgkU82W0PTA0DLgSIA5vFK6c08i8dXzrbLnX06vl38",
oauth_signature="aOM%2FwW2kAowAeHBRvw7faH245p0%3D",
oauth_version="1.0"
Edit: I still get a 401. I used the following code to generate the oauth_signature, so now my Authorization header looks like this: OAuth oauth_timestamp="1376639141", oauth_nonce="BB2D2634F3-99A5-4B64-8CB34E-2314CE9E4FD7", oauth_version="1.0", oauth_consumer_key="mrcD8LuSNKJKFAchKHYi2yY2qwh5tcFMdAs", oauth_signature_method="HMAC-SHA1", oauth_signature="moer8H7xzluAdoAAAFZpv6n4noeu%3D"
NSString *OAuthorizationHeader(NSURL *url, NSString *method, NSData *body, NSString *_oAuthConsumerKey, NSString *_oAuthConsumerSecret, NSString *_oAuthToken, NSString *_oAuthTokenSecret)
{
NSString *_oAuthNonce = [NSString ab_GUID];
NSString *_oAuthTimestamp = [NSString stringWithFormat:#"%d", (int)[[NSDate date] timeIntervalSince1970]];
NSString *_oAuthSignatureMethod = #"HMAC-SHA1";
NSString *_oAuthVersion = #"1.0";
NSMutableDictionary *oAuthAuthorizationParameters = [NSMutableDictionary dictionary];
oAuthAuthorizationParameters[#"oauth_nonce"] = _oAuthNonce;
oAuthAuthorizationParameters[#"oauth_timestamp"] = _oAuthTimestamp;
oAuthAuthorizationParameters[#"oauth_signature_method"] = _oAuthSignatureMethod;
oAuthAuthorizationParameters[#"oauth_version"] = _oAuthVersion;
oAuthAuthorizationParameters[#"oauth_consumer_key"] = _oAuthConsumerKey;
if(_oAuthToken)
oAuthAuthorizationParameters[#"oauth_token"] = _oAuthToken;
// get query and body parameters
NSDictionary *additionalQueryParameters = [NSURL ab_parseURLQueryString:[url query]];
NSDictionary *additionalBodyParameters = nil;
if(body) {
NSString *string = [[[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding] autorelease];
if(string) {
additionalBodyParameters = [NSURL ab_parseURLQueryString:string];
}
}
// combine all parameters
NSMutableDictionary *parameters = [[oAuthAuthorizationParameters mutableCopy] autorelease];
if(additionalQueryParameters) [parameters addEntriesFromDictionary:additionalQueryParameters];
if(additionalBodyParameters) [parameters addEntriesFromDictionary:additionalBodyParameters];
// -> UTF-8 -> RFC3986
NSMutableDictionary *encodedParameters = [NSMutableDictionary dictionary];
for(NSString *key in parameters) {
NSString *value = parameters[key];
encodedParameters[[key ab_RFC3986EncodedString]] = [value ab_RFC3986EncodedString];
}
NSArray *sortedKeys = [[encodedParameters allKeys] sortedArrayUsingFunction:SortParameter context:encodedParameters];
NSMutableArray *parameterArray = [NSMutableArray array];
for(NSString *key in sortedKeys) {
[parameterArray addObject:[NSString stringWithFormat:#"%#=%#", key, encodedParameters[key]]];
}
NSString *normalizedParameterString = [parameterArray componentsJoinedByString:#"&"];
NSString *normalizedURLString = [NSString stringWithFormat:#"%#://%#%#", [url scheme], [url host], [url path]];
NSString *signatureBaseString = [NSString stringWithFormat:#"%#&%#&%#",
[method ab_RFC3986EncodedString],
[normalizedURLString ab_RFC3986EncodedString],
[normalizedParameterString ab_RFC3986EncodedString]];
NSString *key = [NSString stringWithFormat:#"%#&%#",
[_oAuthConsumerSecret ab_RFC3986EncodedString],
(_oAuthTokenSecret) ? [_oAuthTokenSecret ab_RFC3986EncodedString] : #""];
NSData *signature = HMAC_SHA1(signatureBaseString, key);
NSString *base64Signature = [signature base64EncodedString];
NSMutableDictionary *authorizationHeaderDictionary = [[oAuthAuthorizationParameters mutableCopy] autorelease];
authorizationHeaderDictionary[#"oauth_signature"] = base64Signature;
NSMutableArray *authorizationHeaderItems = [NSMutableArray array];
for(NSString *key in authorizationHeaderDictionary) {
NSString *value = authorizationHeaderDictionary[key];
[authorizationHeaderItems addObject:[NSString stringWithFormat:#"%#=\"%#\"",
[key ab_RFC3986EncodedString],
[value ab_RFC3986EncodedString]]];
}
NSString *authorizationHeaderString = [authorizationHeaderItems componentsJoinedByString:#", "];
authorizationHeaderString = [NSString stringWithFormat:#"OAuth %#", authorizationHeaderString];
return authorizationHeaderString;
}
The parameters I pass in to this method are
url: https://api.twitter.com/oauth/request_token, method: POST, body: nil, oAuthConsumerToken: my key, oAuthConsumerSecret: my secret, oAuthToken:nil,oAuthTokenSecret:nil.
EDIT I tried this oauth test console to verify that I'm properly generating the oauth signature, but it appears I need the Member's token and secret:

You haven't included the oauth_signature in the Authorization header.

Related

How can I extract parameters from a non-standard URL NSString object?

I'm diving into iOS development and I have a custom URL scheme for my iPhone app that looks like myApp://?q=200. I have the following code to get the query parameter...
NSString *urlString = [url absoluteString];
NSString *query = [urlString stringByReplacingOccurrencesOfString:#"myApp://?q=" withString:#""];
...but I'd like to make it a bit more future-proof in the event that I add more parameters. How can I extract the "q" parameter in a safer way?
Thanks in advance for your wisdom!
You can split the query returned from the URL by & and = and put them in a dictionary.
NSURL *url = [NSURL URLWithString:#"myApp://?q=200"];
NSArray *query = [[url query] componentsSeparatedByString:#"&"];
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithCapacity:[query count]];
for(NSString *parameter in query)
{
NSArray *kv = [parameter componentsSeparatedByString:#"="];
[parameters setObject:[kv count] > 1 ? [[kv objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSISOLatin1StringEncoding] : [NSNull null]
forKey:[[kv objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSISOLatin1StringEncoding]];
}
NSLog(#"Parameters: %#", parameters);
NSLog(#"q = %#", [parameters objectForKey:#"q"]);
In this example if there is no value for the parameter I just set it to NSNull. This means you would either need to check for NSNull or change the logic to skip keys with values or set them to an empty string.
This from the top of my head could work but doesnt yet include error checking the input
-(NSDictionary*) parameterDictionaryFromString: (NSURL*) url {
//input can be something like: "myApp://?q=one&q2=two&q3=three"
NSString *requestString = [url query];
//now we have q=one&q2=two&q3=three
NSArray *requests = [requestString componentsSeparatedByString: #"&"];
NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionary];
for (NSString *singleParameter in requests) {
NSArray *keyValuePair = [singleParameter componentsSeparatedByString: #"="];
[resultDictionary setObject: [keyValuePair objectAtIndex: 1] forKey: [keyValuePair objectAtIndex: 0]];
}
NSURL *u = [NSURL URLWithString: #"myApp://something?q=1&check=yes"];
NSLog(#"paramStr = %#", [u parameterString]);
return [resultDictionary copy];
}
Break the Query String by Distinct Separator,
Assure Valued Content provided at index:1 (The right-hand side of the query string break)
In valued content then use downstream, or set to upstream variable.
//Your Example:
//#"myApp://?q=200"
//Break:
NSArray *queryParts = [urlString componentsSeparatedByString:#"?q="];
//Assure Content:
if ([[array objectAtIndex:1] length]>0) {
//Setter:
NSString *queryString = [array objectAtIndex:1];
//... Use away...
}
The key is to leverage the NSArray class over StringReplace.

NSMutableArray of Objects

First off I am very new to Objective C and iPhone programming. Now that that is out of the way. I have read through most of the Apple documentation on this and some third party manuals.
I guess I just want to know if I'm going about this the correct way ...
- (NSMutableArray *)makeModel {
NSString *api = #"http://www.mycoolnewssite.com/api/v1";
NSArray *namesArray = [NSArray arrayWithObjects:#"News", #"Sports", #"Entertainment", #"Business", #"Features", nil];
NSArray *urlsArray = [NSArray arrayWithObjects:
[NSString stringWithFormat:#"%#/news/news/25/stories.json", api],
[NSString stringWithFormat:#"%#/news/sports/25/stories.json", api],
[NSString stringWithFormat:#"%#/news/entertainment/25/stories.json", api],
[NSString stringWithFormat:#"%#/news/business/25/stories.json", api],
[NSString stringWithFormat:#"%#/news/features/25/stories.json", api], nil];
NSMutableArray *result = [NSMutableArray array];
for (int i = 0; i < [namesArray count]; i++) {
NSMutableDictionary *objectDict = [NSMutableDictionary dictionary];
NSString *name = (NSString *)[namesArray objectAtIndex:i];
NSString *url = (NSString *)[urlsArray objectAtIndex:i];
[objectDict setObject:name forKey:#"NAME"];
[objectDict setObject:url forKey:#"URL"];
[objectDict setObject:#"NO" forKey:#"HASSTORIES"];
[result addObject:objectDict];
}
return result;
}
The output of the result is ...
(
{
HASSTORIES = NO;
NAME = News;
URL = "http://www.mycoolnewssite.com/api/v1/news/news/25/stories.json";
},
{
HASSTORIES = NO;
NAME = Sports;
URL = "http://www.mycoolnewssite.com/api/v1/news/sports/25/stories.json";
},
{
HASSTORIES = NO;
NAME = Entertainment;
URL = "http://www.mycoolnewssite.com/api/v1/news/entertainment/25/stories.json";
},
{
HASSTORIES = NO;
NAME = Business;
URL = "http://www.mycoolnewssite.com/api/v1/news/business/25/stories.json";
},
{
HASSTORIES = NO;
NAME = Features;
URL = "http://www.mycoolnewssite.com/api/v1/news/features/25/stories.json";
}
)
Any insight would be appreciated ;-)
It looks fine. There can be some minor improvements if you care.
1.
[NSString stringWithFormat:#"%#/news/news/25/stories.json", api]
can be replaced by
[api stringByAppendingString:#"/news/news/25/stories.json"]
if there's no chance the api appears in the middle or accepts other arguments.
2.
NSString *name = (NSString *)[namesArray objectAtIndex:i];
NSString *url = (NSString *)[urlsArray objectAtIndex:i];
The explicit cast is unnecessary. An id can be implicitly casted to and from other ObjC objects.
3.
You could use a convenient method -dictionaryWithObjectsAndKeys: to construct the dictionary in one-shot, so you don't need a temperary dictionary:
[result addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
name, #"NAME",
url, #"URL",
#"NO", #"HASSTORIES", nil]];
4. (optional)
This transform is not useful if the function is not a hot spot.
Since the arrays are only used locally, it's more efficient to use a C array.
static const int arraySize = 5;
NSString* namesCArray[] = {#"News", #"Sports", #"Entertainment", #"Business", #"Features"};
NSString* urlsCArray[arraySize];
urlsArray[0] = [api stringByAppendingString:#"/news/news/25/stories.json"];
...
for (int i = 0; i < arraySize; ++ i) {
...
NSString* name = namesCArray[i];
NSString* url = urlsCArray[i];
...
}
this removes the repeated -count and -objectAtIndex: calls which is very slow compared with direct element access.
5. (optional)
This transform is not useful if the array is short.
You could use fast-enumeration to loop over an ObjC container:
int i = 0;
for (NSString* name in namesArray) {
NSString* url = [urlsArray objectAtIndex:i];
...
++ i;
}
6.
Usually we use [NSNumber numberWithBool:NO] to represent a boxed true/false value, instead of a string #"NO". NSNumber is also used a lot whenever a primitive number (int, float, etc.) cannot be used (e.g. to be stored in an NSArray). I don't know if your API explicitly requires a string NO, so it may not unsuitable for you.

iPhone parsing url for GET params

I have an string which is got from parsing an xml site.
http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500
I want to have an NSString function that will be able to parse the value of c.
Is there a default function or do i have to write it manually.
You could use Regular expression via RegExKit Lite:
http://regexkit.sourceforge.net/RegexKitLite/
Or you could separate the string into components (which is less nice):
NSString *url=#"http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500";
NSArray *comp1 = [url componentsSeparatedByString:#"?"];
NSString *query = [comp1 lastObject];
NSArray *queryElements = [query componentsSeparatedByString:#"&"];
for (NSString *element in queryElements) {
NSArray *keyVal = [element componentsSeparatedByString:#"="];
if (keyVal.count > 0) {
NSString *variableKey = [keyVal objectAtIndex:0];
NSString *value = (keyVal.count == 2) ? [keyVal lastObject] : nil;
}
}
I made a class that does this parsing for you using an NSScanner, as an answer to the same question a few days ago. You might find it useful.
You can easily use it like:
URLParser *parser = [[[URLParser alloc] initWithURLString:#"http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500"] autorelease];
NSString *c = [parser valueForVariable:#"c"]; //c=500
Try the following:
NSURL *url = [NSURL URLWithString:#"http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500"];
NSMutableString *parameterString = [NSMutableString stringWithFormat:#"{%#;}",[url parameterString]];
[parameterString replaceOccurrencesOfString:#"&" withString:#";"];
// Convert string into Dictionary
NSPropertyListFormat format;
NSString *error;
NSDictionary *paramDict = [NSPropertyListSerialization propertyListFromData:[parameterString dataUsingEncoding:NSUTF8StringEncoding] mutabilityOption: NSPropertyListImmutable format:&format errorDescription:&error];
// Now take the parameter you want
NSString *value = [paramDict valueForKey:#"c"];
Here is the native iOS approach using NSURLComponents and NSURLQueryItem classes:
NSString *theURLString = #"http://www.arijasoft.com/givemesomthing.php?a=3434&b=435edsf&c=500";
NSArray<NSURLQueryItem *> *theQueryItemsArray = [NSURLComponents componentsWithString:theURLString].queryItems;
for (NSURLQueryItem *theQueryItem in theQueryItemsArray)
{
NSLog(#"%# %#", theQueryItem.name, theQueryItem.value);
}

Trying to parse twitter trends

Im trying to parse twitter trends but i keep getting a parser error at "as_of". anyone know why this is happening?
EDIT:
Here is the code im using
NSMutableArray *tweets;
tweets = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://search.twitter.com/trends/current.json"];
trendsArray = [[NSMutableArray alloc] initWithArray:[CCJSONParser objectFromJSON:[NSString stringWithContentsOfURL:url encoding:4 error:nil]]];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for (int i = 0; i < [trendsArray count]; i++) {
dict = [[NSMutableDictionary alloc] init];
//[post setObject: [[currentArray objectAtIndex:i] objectForKey:#"query"]];
[dict setObject:[trendsArray objectAtIndex:i] forKey:#"trends"];
//[dict setObject:[trendsArray objectAtIndex:i] forKey:#"query"];
//[post setObject:[trendsArray objectAtIndex:i] forKey:#"as_of"];
[tweets addObject:dict];
//post = nil;
}
I'm not exactly sure what your problem could be but I've had a play with the twitter api and CCJSON and have got some sample code that seems to work. If you cut and paste it into the applicationDidFinishLaunching method of a new project and include the CCJSON files it will just work (hopefully).
This code will take the trends json from twitter, output the as_of value and create an array of trends.
// Make an array to hold our trends
NSMutableArray *trends = [[NSMutableArray alloc] initWithCapacity:10];
// Get the response from the server and parse the json
NSURL *url = [NSURL URLWithString:#"http://search.twitter.com/trends/current.json"];
NSString *responseString = [NSString stringWithContentsOfURL:url encoding:4 error:nil];
NSDictionary *trendsObject = (NSDictionary *)[CCJSONParser objectFromJSON:responseString];
// Output the as_of value
NSLog(#"%#", [trendsObject objectForKey:#"as_of"]);
// We also have a list of trends (by date it seems, looking at the json)
NSDictionary *trendsList = [trendsObject objectForKey:#"trends"];
// For each date in this list
for (id key in trendsList) {
// Get the trends on this date
NSDictionary *trendsForDate = [trendsList objectForKey:key];
// For each trend in this date, add it to the trends array
for (NSDictionary *trendObject in trendsForDate) {
NSString *name = [trendObject objectForKey:#"name"];
NSString *query = [trendObject objectForKey:#"query"];
[trends addObject:[NSArray arrayWithObjects:name, query, nil]];
}
}
// At the point, we have an array called 'trends' which contains all the trends and their queries.
// Lets see it . . .
for (NSArray *array in trends)
NSLog(#"name: '%#' query: '%#'", [array objectAtIndex:0], [array objectAtIndex:1]);
Hope this is useful, comment if you have any questions,
Sam
PS I used this site to visualise the JSON response - it made it much easier to see what is going on - I just cut and paste the JSON from twitter into it :)

Make an NSURL with an encoded plus (%2B)

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?
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"];
The string should be URL encoded.
Here is a category for NSString that will help:
NSString+Additions.h
#interface NSString (Additions)
- (NSString *)stringByURLEncoding;
NSString+Additions.m
#import "NSString+Additions.h"
#implementation NSString (Additions)
- (NSString *)stringByURLEncoding {
return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
}
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.
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:#""];
Solution when using URLComponents (Swift 3):
var params = ["email": "user+ios-default#example.com", "name": "John Brown"]
var components = URLComponents(string: "http://www.example.com")!
components.path = "/login"
components.queryItems = params.map { URLQueryItem(name: $0, value: $1) }
let url_NoFix = components.url!
// http://www.example.com/login?name=John%20Brown&email=user+ios-default#example.com
let cs = CharacterSet(charactersIn: "+").inverted
let q = components.percentEncodedQuery?.addingPercentEncoding(withAllowedCharacters: cs)
components.percentEncodedQuery = q
let url_Fixed = components.url!
// http://www.example.com/login?name=John%20Brown&email=user%2Bios-default#example.com
encode you string by using below code
NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,NULL,(CFStringRef)#"+",kCFStringEncodingUTF8);
this will encode + of you string which will prevent replacement of + by %2b while posting data in post method
To get encoded plus (%2B) (It works with all charcters) use CFURLCreateStringByAddingPercentEscapes as
/**
get parameterized url from url and query parameters.
*/
+(NSString *)getParameterizedUrl:(NSString *)url withParameters:(NSDictionary *)queryDictionary
{
NSMutableArray *mutablePairs = [NSMutableArray array];
for (NSString *key in queryDictionary) {
[mutablePairs addObject:[NSString stringWithFormat:#"%#=%#", CTPercentEscapedQueryStringKeyFromStringWithEncoding(key, NSUTF8StringEncoding), CTPercentEscapedQueryStringValueFromStringWithEncoding(queryDictionary[key], NSUTF8StringEncoding)]];
}
return [[NSString alloc]initWithFormat:#"%#?%#",url,[mutablePairs componentsJoinedByString:#"&"]];
}
static NSString * const kCharactersToBeEscapedInQueryString = #":/?&=;+!##$()',*";
static NSString * CTPercentEscapedQueryStringKeyFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
static NSString * const kCharactersToLeaveUnescapedInQueryStringPairKey = #"[].";
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kCharactersToLeaveUnescapedInQueryStringPairKey, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}
static NSString * CTPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}
And use in your code as
NSMutableDictionary *params = [[NSMutableDictionary alloc]init];
[params setObject:#"2009-05-04T11:22:00+01:00" forKey:#"timestamp"];
NSString *urlString = [self getParameterizedUrl:#"http://www.example.com" withParameters:params];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];