Parse NSURL path and query on iOS

前端 未结 6 811
耶瑟儿~
耶瑟儿~ 2020-12-16 16:42

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

相关标签:
6条回答
  • 2020-12-16 17:05

    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
    
    0 讨论(0)
  • 2020-12-16 17:20

    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);
    
    0 讨论(0)
  • 2020-12-16 17:20

    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.

    0 讨论(0)
  • Sam Soffes created a well maintained Category for NSURL / NSDictionary. It can be found here: https://github.com/samsoffes/sstoolkit/

    0 讨论(0)
  • 2020-12-16 17:25

    You might want to look at pathComponents which returns an array of the components of the URL. Get more information here.

    0 讨论(0)
  • 2020-12-16 17:28

    Introduced in iOS 8 and OS X 10.10 is NSURLQueryItem, which can be used to build queries. From the docs on NSURLQueryItem:

    An NSURLQueryItem object represents a single name/value pair for an item in the query portion of a URL. You use query items with the queryItems property of an NSURLComponents object.

    You can retrieve the query items from a URL by first creating NSURLComponents:

    NSURL *url = [NSURL URLWithString:@"http://stackoverflow.com?q=ios&count=10"];
    NSURLComponents *components = [NSURLComponents componentsWithURL:url 
                                                   resolvingAgainstBaseURL:YES];
    for (NSURLQueryItem *item in components.queryItems) {
        NSLog(@"name: %@, value: %@", item.name, item.value);
    }
    // name: q, value: ios
    // name: count, value: 10
    

    Note that they return value for -queryItems is an array, not a dictionary. This is because the following is a valid URL. Note the two identical "keys", foo.

    http://google.com?foo=bar&foo=baz

    To create a URL via query items, use the designated initializer queryItemWithName:value: and then add them to NSURLComponents to generate an NSURL. For example:

    NSString *urlString = @"http://stackoverflow.com";
    NSURLComponents *components = [NSURLComponents componentsWithString:urlString];
    NSURLQueryItem *search = [NSURLQueryItem queryItemWithName:@"q" value:@"ios"];
    NSURLQueryItem *count = [NSURLQueryItem queryItemWithName:@"count" value:@"10"];
    components.queryItems = @[ search, count ];
    NSURL *url = components.URL; // http://stackoverflow.com?q=ios&count=10
    

    Notice that the question mark and ampersand are automatically handled. Creating an NSURL from a dictionary of parameters is as simple as:

    NSDictionary *queryDictionary = @{ @"q": @"ios", @"count": @"10" };
    NSMutableArray *queryItems = [NSMutableArray array];
    for (NSString *key in queryDictionary) {
        NSURLQueryItem *item = [NSURLQueryItem queryItemWithName:key 
                                                           value:queryDictionary[key]]; 
        [queryItems addObject:item];
    }
    components.queryItems = queryItems;
    

    I've also written a blog post with more details, Building NSURLs with NSURLQueryItems.

    0 讨论(0)
提交回复
热议问题