Best way to parse URL string to get values for keys?

Solution 1:

I also answered this at https://stackoverflow.com/a/26406478/215748.

You can use queryItems in URLComponents.

When you get this property’s value, the NSURLComponents class parses the query string and returns an array of NSURLQueryItem objects, each of which represents a single key-value pair, in the order in which they appear in the original query string.

let url = "http://example.com?param1=value1&param2=param2"
let queryItems = URLComponents(string: url)?.queryItems
let param1 = queryItems?.filter({$0.name == "param1"}).first
print(param1?.value)

Alternatively, you can add an extension on URL to make things easier.

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
    }
}

You can then access the parameter by its name.

let url = URL(string: "http://example.com?param1=value1&param2=param2")!
print(url.queryParameters["param1"])

Solution 2:

edit (June 2018): this answer is better. Apple added NSURLComponents in iOS 7.

I would create a dictionary, get an array of the key/value pairs with

NSMutableDictionary *queryStringDictionary = [[NSMutableDictionary alloc] init];
NSArray *urlComponents = [urlString componentsSeparatedByString:@"&"];

Then populate the dictionary :

for (NSString *keyValuePair in urlComponents)
{
    NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
    NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
    NSString *value = [[pairComponents lastObject] stringByRemovingPercentEncoding];

    [queryStringDictionary setObject:value forKey:key];
}

You can then query with

[queryStringDictionary objectForKey:@"ad_eurl"];

This is untested, and you should probably do some more error tests.