0

Not sure how to build a String in swift apparently. I'd like to send

action=category&data={"id":2,"type":"sheet"}

as a parameterstring in a request. in XCode I've build it like this:

let actionstring = "\"id\":2,\"type\":\"sheet\""
parameters: ["action": "category", "data": actionstring]

If I do a print(actionstring) I get exactly what I want, but when I send the request it looks like this:

action=category&data=%22id%22%3A2%2C%22type%22%3A%22sheet%22

Wain
  • 118,658
  • 15
  • 128
  • 151
catu
  • 888
  • 6
  • 24
  • 1
    what problem is this causing you? – Wain Mar 21 '16 at 16:57
  • How are you sending the request? If it's in a URL then look at this answer: [Characters allowed in a URL](http://stackoverflow.com/a/1856809/887210) –  Mar 21 '16 at 17:08
  • You haven't shown us how the `actionString` was percent escaped (and you've obviously done something to percent escape it), but you're missing the `{` and `}` that you said you wanted. You might want to add those to your `actionString`, if you really wanted it to look like `action=category&data={"id":2,"type":"sheet"}`. Frankly, though, I'm not sure you want it like that. Generally you'd send it like `action=category&data[id]=2&data[type]=sheet` as shown below, unless you're doing something very non-standard in your web service. It's hard to say without more info about your web service. – Rob Mar 21 '16 at 19:08

2 Answers2

1

That is correct for a URL percent encoded string:

import Foundation

let actionstring = "\"id\":2,\"type\":\"sheet\""
let parameters = ["action": "category", "data": actionstring]

var string = ""
for (index, parameter) in parameters.enumerate() {
  string.appendContentsOf("\(parameter.0)=\(parameter.1)")
  if index + 1 < parameters.count { string.append(Character("&")) }
}

print(string.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet()))
// => Optional("action=category&data=%22id%22%3A2,%22type%22%3A%22sheet%22")
  • 1
    FYI, `URLHostAllowedCharacterSet` is not sufficient for percent escaping. If the value contained a `+` or a `&`, for example, it would let those pass unescaped, which would be problematic. If you know that there aren't going to be those characters, you can get away with `URLHostAllowedCharacterSet`, but generally you should manually build your own character set or create a mutable rendition of `URLHostAllowedCharacterSet` and then remove the appropriate characters. See http://stackoverflow.com/a/35912606/1271826. – Rob Mar 21 '16 at 18:24
  • 1
    Good call, I didn't realize those were in there. Thanks! –  Mar 21 '16 at 20:59
1

Generally if you want data to be received as an associative array by the web service in a x-www-form-urlencoded request, you'd do:

action=category&data[id]=2&data[type]=sheet

That will result in data being received as an associative array.

And, as the others have pointed out, if category, 2, or sheet values had any reserved characters (notably, space, +, or & inside those values can cause problems), you'd percent escape those.


The other way to send structured data like this is to construct an application/json request. It just depends upon what your web service is expecting (as the web service implementation is different for these two types of requests). I'm assuming from your question that your web service is expecting x-www-form-urlencoded request, but if you need demonstration of JSON request, let us know.

Rob
  • 415,655
  • 72
  • 787
  • 1,044