1

I have two strings encoded differently for spacing:

let first = "https://joytst.page.link/zMx3nAj9DxwcE1JC9?title=New+calendar+test"
let second = "https://joytst.page.link/zMx3nAj9DxwcE1JC9?title=New%20calendar%20test"

let firstOutput = first.removingPercentEncoding //https://joytst.page.link/zMx3nAj9DxwcE1JC9?title=New+calendar+test
let secondOutput = second.removingPercentEncoding //https://joytst.page.link/zMx3nAj9DxwcE1JC9?title=New calendar test
  1. Why doesn't it remove encoding correctly, since + is a correct encoding for space?

  2. How can I correctly decode both of them, no matter which one I receive?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bartłomiej Semańczyk
  • 59,234
  • 49
  • 233
  • 358
  • What do you mean "+ is a correct encoding for space"? – Joakim Danielson Feb 16 '23 at 14:28
  • According to [this](https://stackoverflow.com/a/6855723/2725435) it is correct. – Bartłomiej Semańczyk Feb 16 '23 at 14:30
  • It says "_Most_ server side scripts would decode..." so it isn't exactly a rule and I assume swift URL handling is more focused on creating and sending URL's rather than receiving and decoding them so this could also be a reason why you don't get the expected result.. – Joakim Danielson Feb 16 '23 at 14:52
  • 1
    Apparently percent encoding is not same thing as URL encoding where space can be encoded as `+` character. – Marek R Feb 16 '23 at 15:02
  • 1
    Isn't percent encoding having "percent" in its name, so "+" having no "%" isn't "decoded"? Is should have been `%2B` to be `+`? – Larme Feb 16 '23 at 15:17

2 Answers2

2

“Why” is a difficult question to answer except for the people who had a hand in implementing CFURLCreateStringByReplacingPercentEscapes. The fact is that it doesn't.

I can speculate that it doesn't because the + for space replacement is not part of RFC 3986: Uniform Resource Identifier (URI): Generic Syntax. It should only be used in the query part of the URL, which is of type application/x-www-form-urlencoded. But this is just my guess.

Anyway, if you want to convert + to space, you should do so before performing percent-decoding, lest you decode %2b into + and then further decode it into a space, leaving no way for your URL to contain a genuine + after decoding.

let firstOutput = first
    .replacingOccurrences(of: "+", with: " ")
    .removingPercentEncoding
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
0

If you could decode a whitespace from two different patters, then when you wanted to do the opposite and encode it which one it should take?

That's the reason why removingPercentEncoding only supports one of them.