다음과 같은 URL이 있습니다. myApp://action/1?parameter=2&secondparameter=3
속성 쿼리를 사용하면 내 URL
parameter=2&secondparameter=3
A의이을 넣어 쉽게 어떤 방법이 NSDictionary
나는 Array
?
정말 고마워
답변
그런 것 :
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
for (NSString *param in [url componentsSeparatedByString:@"&"]) {
NSArray *elts = [param componentsSeparatedByString:@"="];
if([elts count] < 2) continue;
[params setObject:[elts lastObject] forKey:[elts firstObject]];
}
참고 : 이것은 샘플 코드입니다. 모든 오류 사례는 관리되지 않습니다.
답변
queryItems
에서 사용할 수 있습니다 URLComponents
.
이 속성의 값을 가져 오면 NSURLComponents 클래스는 쿼리 문자열을 구문 분석하고 NSURLQueryItem 개체의 배열을 반환합니다. 각 개체는 원래 쿼리 문자열에 나타나는 순서대로 단일 키-값 쌍을 나타냅니다.
빠른
let url = "http://example.com?param1=value1¶m2=param2"
let queryItems = URLComponents(string: url)?.queryItems
let param1 = queryItems?.filter({$0.name == "param1"}).first
print(param1?.value)
또는 URL에 확장을 추가하여 작업을 더 쉽게 할 수 있습니다.
extension URL {
var queryParameters: QueryParameters { return QueryParameters(url: self) }
}
class QueryParameters {
let queryItems: [URLQueryItem]
init(url: URL?) {
queryItems = URLComponents(string: url?.absoluteString ?? "")?.queryItems ?? []
print(queryItems)
}
subscript(name: String) -> String? {
return queryItems.first(where: { $0.name == name })?.value
}
}
그런 다음 이름으로 매개 변수에 액세스 할 수 있습니다.
let url = "http://example.com?param1=value1¶m2=param2"
print(url.queryParameters["param1"])
답변
이 동작에 도움이 될 수있는 확장 기능을 작성해야 할 이유가있었습니다. 먼저 헤더 :
#import <Foundation/Foundation.h>
@interface NSString (XQueryComponents)
- (NSString *)stringByDecodingURLFormat;
- (NSString *)stringByEncodingURLFormat;
- (NSMutableDictionary *)dictionaryFromQueryComponents;
@end
@interface NSURL (XQueryComponents)
- (NSMutableDictionary *)queryComponents;
@end
@interface NSDictionary (XQueryComponents)
- (NSString *)stringFromQueryComponents;
@end
이러한 메서드는 NSString, NSURL 및 NSDictionary를 확장하여 결과를 포함하는 쿼리 구성 요소 문자열 및 사전 개체간에 변환 할 수 있습니다.
이제 관련 .m 코드 :
#import "XQueryComponents.h"
@implementation NSString (XQueryComponents)
- (NSString *)stringByDecodingURLFormat
{
NSString *result = [self stringByReplacingOccurrencesOfString:@"+" withString:@" "];
result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return result;
}
- (NSString *)stringByEncodingURLFormat
{
NSString *result = [self stringByReplacingOccurrencesOfString:@" " withString:@"+"];
result = [result stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return result;
}
- (NSMutableDictionary *)dictionaryFromQueryComponents
{
NSMutableDictionary *queryComponents = [NSMutableDictionary dictionary];
for(NSString *keyValuePairString in [self componentsSeparatedByString:@"&"])
{
NSArray *keyValuePairArray = [keyValuePairString componentsSeparatedByString:@"="];
if ([keyValuePairArray count] < 2) continue; // Verify that there is at least one key, and at least one value. Ignore extra = signs
NSString *key = [[keyValuePairArray objectAtIndex:0] stringByDecodingURLFormat];
NSString *value = [[keyValuePairArray objectAtIndex:1] stringByDecodingURLFormat];
NSMutableArray *results = [queryComponents objectForKey:key]; // URL spec says that multiple values are allowed per key
if(!results) // First object
{
results = [NSMutableArray arrayWithCapacity:1];
[queryComponents setObject:results forKey:key];
}
[results addObject:value];
}
return queryComponents;
}
@end
@implementation NSURL (XQueryComponents)
- (NSMutableDictionary *)queryComponents
{
return [[self query] dictionaryFromQueryComponents];
}
@end
@implementation NSDictionary (XQueryComponents)
- (NSString *)stringFromQueryComponents
{
NSString *result = nil;
for(__strong NSString *key in [self allKeys])
{
key = [key stringByEncodingURLFormat];
NSArray *allValues = [self objectForKey:key];
if([allValues isKindOfClass:[NSArray class]])
for(__strong NSString *value in allValues)
{
value = [[value description] stringByEncodingURLFormat];
if(!result)
result = [NSString stringWithFormat:@"%@=%@",key,value];
else
result = [result stringByAppendingFormat:@"&%@=%@",key,value];
}
else {
NSString *value = [[allValues description] stringByEncodingURLFormat];
if(!result)
result = [NSString stringWithFormat:@"%@=%@",key,value];
else
result = [result stringByAppendingFormat:@"&%@=%@",key,value];
}
}
return result;
}
@end
답변
이 시도 ;)!
NSString *query = @"parameter=2&secondparameter=3"; // replace this with [url query];
NSArray *components = [query componentsSeparatedByString:@"&"];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
for (NSString *component in components) {
NSArray *subcomponents = [component componentsSeparatedByString:@"="];
[parameters setObject:[[subcomponents objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
forKey:[[subcomponents objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
답변
모든 이전 게시물이 URL 인코딩을 제대로 수행하지 않습니다. 다음 방법을 제안합니다.
+(NSString*)concatenateQuery:(NSDictionary*)parameters {
if([parameters count]==0) return nil;
NSMutableString* query = [NSMutableString string];
for(NSString* parameter in [parameters allKeys])
[query appendFormat:@"&%@=%@",[parameter stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet],[[parameters objectForKey:parameter] stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet]];
return [[query substringFromIndex:1] copy];
}
+(NSDictionary*)splitQuery:(NSString*)query {
if([query length]==0) return nil;
NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
for(NSString* parameter in [query componentsSeparatedByString:@"&"]) {
NSRange range = [parameter rangeOfString:@"="];
if(range.location!=NSNotFound)
[parameters setObject:[[parameter substringFromIndex:range.location+range.length] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey:[[parameter substringToIndex:range.location] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
else [parameters setObject:[[NSString alloc] init] forKey:[parameter stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
return [parameters copy];
}
답변
다음은 신속한 확장입니다.
extension NSURL{
func queryParams() -> [String:AnyObject] {
var info : [String:AnyObject] = [String:AnyObject]()
if let queryString = self.query{
for parameter in queryString.componentsSeparatedByString("&"){
let parts = parameter.componentsSeparatedByString("=")
if parts.count > 1{
let key = (parts[0] as String).stringByReplacingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let value = (parts[1] as String).stringByReplacingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
if key != nil && value != nil{
info[key!] = value
}
}
}
}
return info
}
}
답변
Onato 의 이미 매우 깨끗한 답변에 따르면 Swift에서 NSURL에 대한 확장을 작성하여 다음과 같은 쿼리 매개 변수를 얻을 수 있습니다.
예를 들어 URL은 param = some_value 쌍을 포함합니다.
let queryItem = url.queryItemForKey("param")
let value = queryItem.value // would get String "someValue"
확장은 다음과 같습니다.
extension NSURL {
var allQueryItems: [NSURLQueryItem] {
get {
let components = NSURLComponents(URL: self, resolvingAgainstBaseURL: false)!
let allQueryItems = components.queryItems!
return allQueryItems as [NSURLQueryItem]
}
}
func queryItemForKey(key: String) -> NSURLQueryItem? {
let predicate = NSPredicate(format: "name=%@", key)!
return (allQueryItems as NSArray).filteredArrayUsingPredicate(predicate).first as? NSURLQueryItem
}
}