Search code examples
iosswifturlswift4

Swift URL appendingPathComponent converts `?` to `%3F`


let url = URL(string: "https://example.com")
let path = "/somePath?"
let urlWithPath = url?.appendingPathComponent(path)

After appending, the path /somePath? becomes somePath%3F.

The ? becomes a %3F. Question Mark is replaced with the percent-encoded escape characters.

The URL does output correctly if I use:

let urlFormString = URL(string:"https://example.com/somePath?")

Why does appendingPathComponent convert ? to %3F?

How can I use appendingPathComponent if the path component contains a question mark?


Solution

  • The generic format of URL is the following:

    scheme:[//[userinfo@]host[:port]]path[?query][#fragment]
    

    The thing you have to realize is that the ? is not part of the path. It is a separator between path and query.

    If you try to add ? to path, it must be URL-encoded because ? is not a valid character for a path component.

    The best solution would be to drop ? from path. It has no meaning there. However, if you have a partial URL which you want to append to a base URL, then you should join them as strings:

    let url = URL(string: "https://example.com")
    let path = "/somePath?"
    let urlWithPath = url.flatMap { URL(string: $0.absoluteString + path) }
    

    In short, appendingPathComponent is not a function that should be used to append URL query.