使用 NSURLComponents 和 NSURLQueryItem 来进行更规范的 URL 字符串拼接

技术博客 (258) 2023-11-22 09:01:01

在日常的编程工作中,经常需要拼接URL字符串,可能直接写成如下的形式:

NSString *urlStr = @"https://www.demo.com/query?name=Jack";

对于比较简短的url字符串,这种写法直观方便。但是如果需要拼接一大串的query语句的话,就会非常地长(虽然Objective-C语法本身也是非常的长),譬如:

NSString *urlStr = 
[NSString stringWithFormat:@"https://www.demo.com/query?name=%@&gender=%@&lng=%@&lat=%@&age=%@", @"Jack", @"male", @"121", @"31", @"20"];

此时如果你的显示器不是特别宽的话,应该已经自动换行了,并且占位符也比较多,看起来比较乱,后续维护也会比较麻烦。 此时可以使用NSURLComponentsNSURLQueryItem来进行拼接:

NSURLComponents *components = [NSURLComponents componentsWithString:@"https://www.demo.com/query"];
NSMutableArray<NSURLQueryItem *> *queryItems = @[].mutableCopy;
NSURLQueryItem *nameItem = [NSURLQueryItem queryItemWithName:@"name" value:@"Jack"];
NSURLQueryItem *genderItem = [NSURLQueryItem queryItemWithName:@"gender" value:@"male"];
NSURLQueryItem *lngItem = [NSURLQueryItem queryItemWithName:@"lng" value:@"121"];
NSURLQueryItem *latItem = [NSURLQueryItem queryItemWithName:@"lat" value:@"31"];
NSURLQueryItem *ageItem = [NSURLQueryItem queryItemWithName:@"age" value:@"20"];
[queryItems addObject:nameItem];
[queryItems addObject:genderItem];
[queryItems addObject:lngItem];
[queryItems addObject:latItem];
[queryItems addObject:ageItem];
components.queryItems = queryItems;

NSURL *url = components.URL;
...

这样写就比较清晰,并且后期维护起来也相对容易些,当然你也可以用字典简单封装一下NSURLQueryItem数组(在绝大多数的场景中适用):

- (NSArray<NSURLQueryItem *> *)queryItemsWithParameters:(NSDictionary<NSString *, NSString *> *)dict {
    if ([dict isKindOfClass:[NSDictionary class]] && [dict count] > 0) {

        NSMutableArray<NSURLQueryItem *> *arrM = @[].mutableCopy;
        for (NSString *keyStr in dict.allKeys) {
            NSURLQueryItem *item = [NSURLQueryItem queryItemWithName:keyStr value:dict[keyStr]];
            [arrM addObject:item];
        }
        return arrM;
    }

    return nil;
}



    NSDictionary *dict = @{@"name": @"Jack",
                           @"gender": @"male",
                           @"lng": @"121",
                           @"lat": @"31",
                           @"age": @"20"};
                    
    components.queryItems = [self queryItemsWithParameters:dict];                           

THE END

发表回复