在iOS上解析NSURL路径和查询

时间:2009-12-27 23:35:46

标签: ios objective-c cocoa-touch nsurl

是否有任何标准对象或函数来解析NSURL的组件?显然我可以写一个,但为什么重新发明轮子?

[NSURL path]将返回NSString,如"argX=x&argY=y&argZ=z" 我宁愿回来的是一个填充了{@"argX" => @"x", @"argY" => @"y", @"argZ" = @"z"}

的字典

对于返回类似“/ partA / partB / partC”的字符串的路径,我宁愿得到一个结构为{[0] => @"partA", [1] => @"partB", [2] => @"partC"}的数组

我意识到这是一个非常具体的问题,但它似乎是很多人想要的东西。

这适用于iOS!显然NSURL在macOS上有不同的功能。

6 个答案:

答案 0 :(得分:12)

好吧,我厌倦了,并写了一个解决方案,通过类别扩展NSString。我还没有测试过,但是如果你想使用它,那就去吧。

@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

它被称为:

NSMutableDictionary *parsedQuery = [[myNSURL query] explodeToDictionaryInnerGlue:@"=" outterGlue=@"&"]

要解析NSURL的路径部分(即@“/ partA / partB / partC”),只需调用:

NSArray *parsedPath = [[nyNSURL path] componentsSeperatedByString:@"/"];

请注意,由于前导/!

,parsedPath [0]将为空字符串

编辑 - 这是NSURL的类别扩展,以满足您的使用乐趣。它剥离了初始的“/”,因此你没有空的0索引。

@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

答案 1 :(得分:11)

Sam Soffes为NSURL / NSDictionary创建了一个维护良好的类别。可在此处找到:https://github.com/samsoffes/sstoolkit/

答案 2 :(得分:10)

您可能希望查看pathComponents,它返回URL组件的数组。获取更多信息here

答案 3 :(得分:5)

下面是我用来解析查询字符串

的内容
// 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);

答案 4 :(得分:2)

如果您决定编写一个(我不确定是否有获取所需组件的现有方法),您可能需要使用NSString的componentsSeparatedByString

答案 5 :(得分:2)

在iOS 8和OS X 10.10中引入NSURLQueryItem,可用于构建查询。来自NSURLQueryItem上的文档:

  

NSURLQueryItem对象表示URL查询部分中项目的单个名称/值对。您将查询项与NSURLComponents对象的queryItems属性一起使用。

您可以先创建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

请注意,-queryItems的返回值是数组,而不是字典。这是因为以下是有效的URL。请注意两个相同的&#34;键&#34;,foo

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

要通过查询项创建网址,请使用指定的初始值设定项queryItemWithName:value:,然后将其添加到NSURLComponents以生成NSURL。例如:

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

请注意,问号和&符号会自动处理。从参数字典创建NSURL非常简单:

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;

我还撰写了一篇博文,其中详细介绍了Building NSURLs with NSURLQueryItems