I would like to send some URL encoded data from a Swift app to a PHP API where the data is decoded again.
While this works fine most of the time, I know became aware that PHP urldecode handles the + sign differently than the Swift addingPercentEncoding and decodes the + to a space.
How can this be avoided?
// Swift
let data = "some+test"
let encodedData = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) // some+test
sendToMyServer(encodedData)
// PHP
$encodedData = $receivedData; // some+text
$decodedData = urldecode($encodedData); // some text
It seems that Swift does not consider the + sign in any of its build in (inverted) char sets:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
Is there a reason why PHP handles the + sign in this way?
What is the "correct" way to solve this? I assume I could simple define a custom char set which includes the + sign, but I am not sure if this might lead to other unexpected side effects. Is this safe or are there other differences in PHP urldecode which needs to be considered?
For the reason:
Doc of
CharacterSet.urlHostAllowed:If we then go to implicitly linked doc of
URLComponentsThe doc of PhP
urldecodesays:The
urlencodesays:So iOS uses the
RFC 3986and PhP doesn't.Solution:
Use the same encoding/decoding, by changing it on iOS or in the server.
For the server changes:
To use the same as iOS on the server side, use
rawurldecode(orrawurlencodeif needed), as it says:and
For the iOS changes:
See Sajjad's answer