Are there any standard objects or functions to parse an NSURL's components? Clearly I could write one, but why re-invent the wheel?
[NSURL path] will return an NSString like "argX=x&argY=y&argZ=z"
What I would rather get back is a dictionary populated with {@"argX" => @"x", @"argY" => @"y", @"argZ" = @"z"}
For the path, which returns a string like "/partA/partB/partC", I would rather get an array with the structure {[0] => @"partA", [1] => @"partB", [2] => @"partC"}
I realize this is a pretty specific ask, but it seems like something a lot of people would want.
This is for iOS! Apparently NSURL has different functions on macOS.
Alright, I got antsy and wrote a solution for extending NSString through Categories. I haven't tested this yet, but if you want to use it, go for it.
@interface NSString (ParseCategory)
- (NSMutableDictionary *)explodeToDictionaryInnerGlue:(NSString *)innerGlue outterGlue:(NSString *)outterGlue;
@end
@implementation NSString (ParseCategory)
- (NSMutableDictionary *)explodeToDictionaryInnerGlue:(NSString *)innerGlue outterGlue:(NSString *)outterGlue {
    // Explode based on outter glue
    NSArray *firstExplode = [self componentsSeparatedByString:outterGlue];
    NSArray *secondExplode;
    // Explode based on inner glue
    NSInteger count = [firstExplode count];
    NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithCapacity:count];
    for (NSInteger i = 0; i < count; i++) {
        secondExplode = [(NSString *)[firstExplode objectAtIndex:i] componentsSeparatedByString:innerGlue];
        if ([secondExplode count] == 2) {
            [returnDictionary setObject:[secondExplode objectAtIndex:1] forKey:[secondExplode objectAtIndex:0]];
        }
    }
    return returnDictionary;
}
@end
It's called like this:
NSMutableDictionary *parsedQuery = [[myNSURL query] explodeToDictionaryInnerGlue:@"=" outterGlue=@"&"]
For parsing the path portion of the NSURL (ie @"/partA/partB/partC"), just call this:
NSArray *parsedPath = [[nyNSURL path] componentsSeperatedByString:@"/"];
Be aware that parsedPath[0] will be an empty string because of the leading /!
EDIT - Here is a Category extension to NSURL for your usage pleasure. It strips the initial "/" so you don't have an empty 0 index.
@implementation NSURL (ParseCategory)
- (NSArray *)pathArray {
    // Create a character set for the slash character
    NSRange slashRange;
    slashRange.location = (unsigned int)'/';
    slashRange.length = 1;
    NSCharacterSet *slashSet = [NSCharacterSet characterSetWithRange:slashRange];
    // Get path with leading (and trailing) slashes removed
    NSString *path = [[self path] stringByTrimmingCharactersInSet:slashSet];
    return [path componentsSeparatedByCharactersInSet:slashSet];
}
- (NSDictionary *)queryDictionary {
    NSDictionary *returnDictionary = [[[[self query] explodeToDictionaryInnerGlue:@"=" outterGlue:@"&"] copy] autorelease];
    return returnDictionary;
}
@end
                        Sam Soffes created a well maintained Category for NSURL / NSDictionary. It can be found here: https://github.com/samsoffes/sstoolkit/
You might want to look at pathComponents which returns an array of the components of the URL. Get more information here.
Heres what i use to parse the query string
// Parse the individual parameters
// parameters = @"hello=world&foo=bar";
NSMutableDictionary *dictParameters = [[NSMutableDictionary alloc] init];
NSArray *arrParameters = [parameters componentsSeparatedByString:@"&"];
for (int i = 0; i < [arrParameters count]; i++) {
    NSArray *arrKeyValue = [[arrParameters objectAtIndex:i] componentsSeparatedByString:@"="];
    if ([arrKeyValue count] >= 2) {
        NSMutableString *strKey = [NSMutableString stringWithCapacity:0];
        [strKey setString:[[[arrKeyValue objectAtIndex:0] lowercaseString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
        NSMutableString *strValue   = [NSMutableString stringWithCapacity:0];
        [strValue setString:[[[arrKeyValue objectAtIndex:1]  stringByReplacingOccurrencesOfString:@"+" withString:@" "] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
        if (strKey.length > 0) [dictParameters setObject:strValue forKey:strKey];
    }
}
NSLog(@"Parameters: %@", dictParameters);
                        If you do decide to write one (I'm not sure there are existing methods of getting the components you want), you might want to use NSString's componentsSeparatedByString.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With