4

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!

BeachRunnerFred
  • 18,070
  • 35
  • 139
  • 238

3 Answers3

2

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.

Joe
  • 56,979
  • 9
  • 128
  • 135
1

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];

}

Mario
  • 4,530
  • 1
  • 21
  • 32
0
  1. Break the Query String by Distinct Separator,
  2. Assure Valued Content provided at index:1 (The right-hand side of the query string break)
  3. 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.

Newbyman
  • 1,144
  • 10
  • 14