Objective-C: How to add a query parameter to NSURL?

Say I have an NSURL ? Regardless of whether it already has an empty query string, how to add one or more parameters to query for NSURL ? 1. Does anyone know about the implementation of this function?

 - (NSURL *)URLByAppendingQueryString:(NSString *)queryString 

So that it satisfies this NSURL+AdditionsSpec.h file:

 #import "NSURL+Additions.h" #import "Kiwi.h" SPEC_BEGIN(NSURL_AdditionsSpec) describe(@"NSURL+Additions", ^{ __block NSURL *aURL; beforeEach(^{ aURL = [[NSURL alloc] initWithString:@"http://www.example.com"]; aURLWithQuery = [[NSURL alloc] initWithString:@"http://www.example.com?key=value"]; }); afterEach(^{ [aURL release]; [aURLWithQuery release]; }); describe(@"-URLByAppendingQueryString:", ^{ it(@"adds to plain URL", ^{ [[[[aURL URLByAppendingQueryString:@"key=value&key2=value2"] query] should] equal:@"key=value&key2=value2"]; }); it(@"appends to the existing query sting", ^{ [[[[aURLWithQuery URLByAppendingQueryString:@"key2=value2&key3=value3"] query] should] equal:@"key=value&key2=value2&key3=value3"]; }); }); }); SPEC_END 
+50
query-string objective-c nsurl
Jun 10 '11 at 5:00 p.m.
source share
8 answers

Here's an implementation that passes your specifications:

 @implementation NSURL (Additions) - (NSURL *)URLByAppendingQueryString:(NSString *)queryString { if (![queryString length]) { return self; } NSString *URLString = [[NSString alloc] initWithFormat:@"%@%@%@", [self absoluteString], [self query] ? @"&" : @"?", queryString]; NSURL *theURL = [NSURL URLWithString:URLString]; [URLString release]; return theURL; } @end 

And here is the implementation for NSString :

 @implementation NSString (Additions) - (NSURL *)URLByAppendingQueryString:(NSString *)queryString { if (![queryString length]) { return [NSURL URLWithString:self]; } NSString *URLString = [[NSString alloc] initWithFormat:@"%@%@%@", self, [self rangeOfString:@"?"].length > 0 ? @"&" : @"?", queryString]; NSURL *theURL = [NSURL URLWithString:URLString]; [URLString release]; return theURL; } // Or: - (NSString *)URLStringByAppendingQueryString:(NSString *)queryString { if (![queryString length]) { return self; } return [NSString stringWithFormat:@"%@%@%@", self, [self rangeOfString:@"?"].length > 0 ? @"&" : @"?", queryString]; } @end 
+39
Jun 10 2018-11-21T00:
source share

Since iOS 7 , you can use NSURLComponents , which is very easy to use. Take a look at these examples:

Example 1

 NSString *urlString = @"https://mail.google.com/mail/u/0/?shva=1#inbox"; NSURLComponents *components = [[NSURLComponents alloc] initWithString:urlString]; NSLog(@"%@ - %@ - %@ - %@", components.scheme, components.host, components.query, components.fragment); 

Example 2

 NSString *urlString = @"https://mail.google.com/mail/u/0/?shva=1#inbox"; NSURLComponents *components = [[NSURLComponents alloc] initWithString:urlString]; if (components) { //good URL } else { //bad URL } 

Example 3

 NSURLComponents *components = [NSURLComponents new]; [components setScheme:@"https"]; [components setHost:@"mail.google.com"]; [components setQuery:@"shva=1"]; [components setFragment:@"inbox"]; [components setPath:@"/mail/u/0/"]; [self.webview loadRequest:[[NSURLRequest alloc] initWithURL:[components URL]]]; 

But you can do many other things with NSURLComponents, take a look at the NSURLComponents class link to Apple documentation or this link: http://nshipster.com/nsurl/

+64
Feb 26 '14 at 18:18
source share

Modern way iOS8 +

adding (or replacing the ref value), if exists) ref = impm for the url that is on min60.com

 if ([[url host] hasSuffix:@"min60.com"]) { NSURLComponents *components = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO]; NSURLQueryItem * newQueryItem = [[NSURLQueryItem alloc] initWithName:@"ref" value:@"impm"]; NSMutableArray * newQueryItems = [NSMutableArray arrayWithCapacity:[components.queryItems count] + 1]; for (NSURLQueryItem * qi in components.queryItems) { if (![qi.name isEqual:newQueryItem.name]) { [newQueryItems addObject:qi]; } } [newQueryItems addObject:newQueryItem]; [components setQueryItems:newQueryItems]; url = [components URL]; } 
+22
Jan 22 '16 at 22:04
source share

Just a friendly post for those who do not want to write boilerplate code when building NSURL using NSURLComponents .
Since iOS8 has NSURLQueryItem , it helps to quickly speed up the creation of a URL request.

I wrote a slightly convenient category to facilitate the work you can get here: URLQueryBuilder
Here is an example of how easy it is to work with it:

 NSString *baseURL = @"https://google.com/search"; NSDictionary *items = @{ @"q" : @"arsenkin.com", @"hl" : @"en_US", @"lr" : @"lang_en" }; NSURL *URL = [NSURL ars_queryWithString:baseURL queryElements:items]; // https://google.com/search?q=arsenkin.com&hl=en_US&lr=lang_en 
+7
Nov 06 '15 at 9:05
source share

If you use RestKit, it provides add-ons for NSString . One of them:

 - (NSString *)stringByAppendingQueryParameters:(NSDictionary *)queryParameters 

So you can do:

 NSDictionary *shopParams = [NSDictionary dictionaryWithKeysAndObjects: @"limit",@"20", @"location",@"latitude,longitude", nil]; NSString *pathWithQuery = [@"/api/v1/shops.json" stringByAppendingQueryParameters:shopParams] 
+5
Jul 18 2018-12-18T00:
source share

I have an extension to NSURLComponents that adds a request element to swift:

 extension NSURLComponents { func appendQueryItem(name name: String, value: String) { var queryItems: [NSURLQueryItem] = self.queryItems ?? [NSURLQueryItem]() queryItems.append(NSURLQueryItem(name: name, value: value)) self.queryItems = queryItems } } 

To use

 let components = NSURLComponents(string: urlString)! components.appendQueryItem(name: "key", value: "value") 
+4
Apr 08 '16 at 2:34 on
source share

NSURL is not changed, so you cannot implement this function directly based on NSURL. Instead, you'll need to get a string representation of the URL, add your parameters to it, and then create a new NSURL.

This does not seem like a good solution. If there is no good reason, it is better to work with strings until the last moment and create only NSURL when you have a fully formed request.

0
Jun 10 '11 at 19:09
source share

The answers above mention NSURLComponents, this is a good class for handling URLs.

My answer is this:

Create a category with NSURL, for example NSURL + Additions.h. Then add the following method and implement it.

 - (NSURL *)URLByAppendingQueryParameters:(NSDictionary *)queryParameters { if (queryParameters.count == 0) { return self; } NSArray *queryKeys = [queryParameters allKeys]; NSURLComponents *components = [[NSURLComponents alloc] initWithURL:self resolvingAgainstBaseURL:NO]; NSMutableArray * newQueryItems = [NSMutableArray arrayWithCapacity:1]; for (NSURLQueryItem * item in components.queryItems) { if (![queryKeys containsObject:item.name]) { [newQueryItems addObject:item]; } } for (NSString *key in queryKeys) { NSURLQueryItem * newQueryItem = [[NSURLQueryItem alloc] initWithName:key value:queryParameters[key]]; [newQueryItems addObject:newQueryItem]; } [components setQueryItems:newQueryItems]; return [components URL]; } 
0
May 18 '17 at 7:59
source share



All Articles