4

I've got to send a https GET request to a web service in my iPhone app which is developing in Swift 1.2.

I am trying to construct query string parameters but got to encode them before send to server.

All good but not working when password contains '&' charcter. Expect to encode '&' character to '%26' but NOT working...

Just done a test when having '%'. Works as expected with '%' providing '%25'. But NOT convert '&' sign....

Tried following ways:

var testPassword1: String = "mypassword&1"

var testPassword2: String = "mypassword%1"


// Try to encode 'testPassword1'
testPassword1.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)! 
testPassword1.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!


// Try to encode 'testPassword2'
testPassword2.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
testPassword2.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!

I've done the above tests and following are the response

enter image description here

Would like to know the correct way to do this. Thanks.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
JibW
  • 4,538
  • 17
  • 66
  • 101

3 Answers3

3

You should use NSURLComponents for your task.

Given a URL string, create a url-components:

let urlString = "http://example.com"
let urlComponents = NSURLComponents(string: urlString)!

Given a query parameter container (possibly a dictionary, or an array of (String, String?) tuple), create an array of NSURLQueryItems:

let queryParameters: [String: String?] = ["param": "az09-._~!$&'()*+,;=:@/?", "reserved": ":/?#[]@!$&'()*+,;="]
var queryItems = queryParameters.map { NSURLQueryItem(name: $0.0, value: $0.1) }

Append the query-component to the url-components:

urlComponents.queryItems = queryItems.count > 0 ? queryItems : nil

print(urlComponents.string!)

prints:

http://example.com?reserved=:/?%23%5B%5D@!$%26'()*+,;%3D&param=az09-._~!$%26'()*+,;%3D:@/?
CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67
0

I used such an utility method to URL-encode values in GET-requests:

@interface NSString (Ext)

@property (nonatomic, readonly) NSString *urlEncoded;

@end

@implementation NSString (Ext)

- (NSString *)urlEncoded {
    NSMutableCharacterSet *const allowedCharacterSet = [NSCharacterSet URLQueryAllowedCharacterSet].mutableCopy;
    // See https://en.wikipedia.org/wiki/Percent-encoding
    [allowedCharacterSet removeCharactersInString:@"!*'();:@&=+$,/?#[]"]; // RFC 3986 section 2.2 Reserved Characters (January 2005)
    NSString *const urlEncoded = [self stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
    return urlEncoded;
}

@end
werediver
  • 4,667
  • 1
  • 29
  • 49
  • 1
    While this is "strict" (all reserved chars will be escaped) it may cause troubles with values which are URLs. Thus, `URLComponents` will not escape the following chars for "values" in the query component: `/?@!$'()*+,;` This is safe, since these chars are not delimiters in the query component. – CouchDeveloper Apr 21 '16 at 16:39
0

If you need to encode the & character, you can use the following:

var testPassword1: String = "mypassword&1"
testPassword1.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
testPassword1.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet(charactersInString: "&").invertedSet)!
ryantxr
  • 4,119
  • 1
  • 11
  • 25