2

In my app, I need to send to a server a base64-encoded string as a query parameter, eg.

&data=AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)==

Problem is, anything works just fine when there isn't a plus sign in my string: on the other hand, everytime there's one, the server code doesn't behave correctly.

I noticed there are escaping functions (eg. addingPercentEncoding) but they don't work with the plus sign.

Aside from removing all the pluses "manually" (eg. with a regex), is there anything else I can do?

At the moment anything works fine if I use:

string.replacingOccurrences(of: "+", with: "%2B")

2 Answers2

2

The server is probably interpreting the + sign as a space because it is often used in query parameters as a substitute for a space. addPercentEncoding isn't going to help you because it only translates non ASCII characters.

You'll need to manually replace + with %2B as you are doing.

.... although

NSString has a version of addPercentEncoding that also takes a CharacterSet as a parameter. So you could create a Characterset with all the base64 characters in it except + using init(charactersIn:) i.e.

let safeChars = Characterset(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrtuvwxyz0123456789/=")
JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • 1
    @3000 There is another - probably better - way, see updated answer. – JeremyP Nov 28 '17 at 10:02
  • My only doubt is: how can I include / and exclude +? It looks like you can add symbols, not single symbols (but of course I could be wrong) –  Nov 28 '17 at 10:29
  • 1
    @3000 Create the ChacaterSet with [init(charactersInString:)](https://developer.apple.com/documentation/foundation/characterset/1780137-init) – JeremyP Nov 28 '17 at 10:32
2

One good way to construct a URL is to use URLComponents. This should work in almost all cases, and an example is shown below:

let base64 = "AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)=="
var components = URLComponents(string: "https://example.com")
components?.queryItems = [ URLQueryItem(name: "data", value: "AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)==") ]

let url = components?.url

Result:

https://example.com?data=AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)%3D%3D

However, in your particular case, it seems the the server is not correctly handling the + and you need to work around that issue similar to what you have above. The better fix would be for the server to be changed to correctly process the URL.

let base64 = "AwGZnyx+JUi0PFJoyYSEDpgtlrxP(cut...)=="
var components = URLComponents(string: "https://example.com")
components?.queryItems = [ URLQueryItem(name: "data", value: base64) ]

let urlString = components?.string.replacingOccurrences(of: "+", with: "%2B")

Result:

https://example.com?data=AwGZnyx%252BJUi0PFJoyYSEDpgtlrxP(cut...)%3D%3D

picciano
  • 22,341
  • 9
  • 69
  • 82