现象
在日常的编程工作中,经常需要拼接URL字符串,可能直接写成如下的形式:
1
| NSString *urlStr = @"https://www.demo.com/query?name=Jack";
|
对于比较简短的url字符串,这种写法直观方便。但是如果需要拼接一大串的query语句的话,就会非常地长(虽然Objective-C语法本身也是非常的长),譬如:
1 2
| NSString *urlStr = [NSString stringWithFormat:@"https://www.demo.com/query?name=%@&gender=%@&lng=%@&lat=%@&age=%@", @"Jack", @"male", @"121", @"31", @"20"];
|
此时如果你的显示器不是特别宽的话,应该已经自动换行了,并且占位符也比较多,看起来比较乱,后续维护也会比较麻烦。
改进
此时可以使用 NSURLComponents
和 NSURLQueryItem
来进行拼接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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数组(在绝大多数的场景中适用):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| - (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];
|