iosswifturlcomponents

How to fix URLQueryItem in swift


I need to pass an query param to my URLComponents:

URLQueryItem(name: "scope", value: "channel%3Amanage%3Apolls+channel%3Aread%3Apolls")

but when i see the url in debug i see this :

scope=channel%253Amanage%253Apolls+channel%253Aread%253Apolls

The %3 transforms in %253. Why does this happen?


Solution

  • Don’t percent-encode the value you supply to URLQueryItem. URLQueryItem does that for you. As it is, you are double percent-encoding it (i.e., it is percent-encoding the % of your percent-encoded string).

    So, instead, simply supply the simple string, and let URLComponents take care of it:

    let queryItem = URLQueryItem(name: "scope", value: "channel:manage:polls+channel:read:polls")
    

    As an aside, the : characters do not need to be percent-encoded when encountered within a query, anyway. E.g.:

    let queryItem = URLQueryItem(name: "scope", value: "channel:manage:polls+channel:read:polls")
    
    var components = URLComponents(string: "https://example.com")
    components?.queryItems = [
        queryItem
    ]
    
    guard let url = components?.url else { return }
    
    print(url) // https://example.com?scope=channel:manage:polls+channel:read:polls
    

    See RFC3986, in which, if you trace query back to pchar, you will see that : does not need to be escaped.

    But if there really was anything in that query that needed percent-encoding, URLQueryItem and URLComponents would take care of it for you. (The one exception is the + character as discussed here; but I assume from your example that you didn’t want that escaped anyway.)