iOS 上解析 NSURL 路径并查询

发布于 2024-08-16 21:22:08 字数 457 浏览 8 评论 0 原文

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

[NSURL path] 将返回一个 NSString,如 "argX=x&argY=y&argZ=z" 我宁愿拿回一本填充有 {@"argX" =>; 的字典。 @“x”,@“argY”=> @"y", @"argZ" = @"z"}

对于返回像“/partA/partB/partC”这样的字符串的路径,我宁愿得到一个具有结构 { [0] => @“A部分”,[1] => @“partB”,[2] => @“partC”}

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

这是针对 iOS 的!显然 NSURL 在 macOS 上有不同的功能。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

居里长安 2024-08-23 21:22:08

好吧,我很烦躁,写了一个通过类别扩展 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

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
小兔几 2024-08-23 21:22:08

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

Sam Soffes created a well maintained Category for NSURL / NSDictionary. It can be found here: https://github.com/samsoffes/sstoolkit/

别在捏我脸啦 2024-08-23 21:22:08

您可能需要查看 pathComponents,它返回 URL 组件的数组。获取更多信息 此处

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

朮生 2024-08-23 21:22:08

这是我用来解析查询字符串的内容

// 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);

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);
╰◇生如夏花灿烂 2024-08-23 21:22:08

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

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.

不奢求什么 2024-08-23 21:22:08

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

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

您可以通过首先创建 NSURLComponents 从 URL 检索查询项:

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。请注意两个相同的“键”,foo

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

要通过查询项创建 URL,请使用指定的初始值设定项 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;

我还写了一篇包含更多详细信息的博客文章,使用 NSURLQueryItems 构建 NSURL

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文