Search code examples
nsurl

NSURL pull out a single value for a key in a parameter string


I have an NSURL:

serverCall?x=a&y=b&z=c

What is the quickest and most efficient way to get the value of y?

Thanks


Solution

  • UPDATE:

    Since 2010 when this was written, it seems Apple has released a set of tools for that purpose. Please see the answers below for those.

    Old-School Solution:

    Well I know you said "the quickest way" but after I started doing a test with NSScanner I just couldn't stop. And while it is not the shortest way, it is sure handy if you are planning to use that feature a lot. I created a URLParser class that gets these vars using an NSScanner. The use is a simple as:

    URLParser *parser = [[[URLParser alloc] initWithURLString:@"http://blahblahblah.com/serverCall?x=a&y=b&z=c&flash=yes"] autorelease];
    NSString *y = [parser valueForVariable:@"y"];
    NSLog(@"%@", y); //b
    NSString *a = [parser valueForVariable:@"a"];
    NSLog(@"%@", a); //(null)
    NSString *flash = [parser valueForVariable:@"flash"];
    NSLog(@"%@", flash); //yes
    

    And the class that does this is the following (*source files at the bottom of the post):

    URLParser.h

    @interface URLParser : NSObject {
        NSArray *variables;
    }
    
    @property (nonatomic, retain) NSArray *variables;
    
    - (id)initWithURLString:(NSString *)url;
    - (NSString *)valueForVariable:(NSString *)varName;
    
    @end
    

    URLParser.m

    @implementation URLParser
    @synthesize variables;
    
    - (id) initWithURLString:(NSString *)url{
        self = [super init];
        if (self != nil) {
            NSString *string = url;
            NSScanner *scanner = [NSScanner scannerWithString:string];
            [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
            NSString *tempString;
            NSMutableArray *vars = [NSMutableArray new];
            [scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
            while ([scanner scanUpToString:@"&" intoString:&tempString]) {
                [vars addObject:[tempString copy]];
            }
            self.variables = vars;
            [vars release];
        }
        return self;
    }
    
    - (NSString *)valueForVariable:(NSString *)varName {
        for (NSString *var in self.variables) {
            if ([var length] > [varName length]+1 && [[var substringWithRange:NSMakeRange(0, [varName length]+1)] isEqualToString:[varName stringByAppendingString:@"="]]) {
                NSString *varValue = [var substringFromIndex:[varName length]+1];
                return varValue;
            }
        }
        return nil;
    }
    
    - (void) dealloc{
        self.variables = nil;
        [super dealloc];
    }
    
    @end
    

    *if you don't like copying and pasting you can just download the source files - I made a quick blog post about this here.