Swift encode URL: 5 fatal errors and how to avoid them

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Swift encode URL: why your code breaks on Cyrillic and spaces



Every developer who has ever sent a network request in Swift has faced this pain: you form a URL, add parameters, and the server returns a 400 error or, even worse, silently ignores the request. Sound familiar? Most often, the problem lies in incorrect URL encoding. It seems simple enough — take a string, replace spaces with %20, and you're done. But Swift (like any strict language) does not tolerate sloppy work.



In this article, we will break down the 5 most common errors when doing Swift encode URL, which gather thousands of views on Stack Overflow. You will learn how to avoid them and write reliable code that works with any data — from English letters to complex Cyrillic and special characters.



Error #1: Using addingPercentEncoding with the wrong character set



This is perhaps the most popular pitfall. Many beginners see the method addingPercentEncoding(withAllowedCharacters:) and think: "Oh, perfect!". But they pass .urlHostAllowed or .urlPathAllowed for the entire URL. The result — a crash or an incorrect request.



Why doesn't this work?



Each part of the URL (scheme, host, path, query parameters) has its own allowed character set. If you encode the entire URL as a host, you will lose slashes and colons. If you encode it as a path, you will break the query string.



// ❌ Error: encoding the entire URL as a hostlet urlString = "https://example.com/path?name=Ivan & surname=Petrov"let encoded = urlString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)// Result: "https%3A%2F%2Fexample.com%2F%D0%BF%D1%83%D1%82%D1%8C%3Fname%3D%D0%98%D0%B2%D0%B0%D0%BD%20%26%20%D1%84%D0%B0%D0%BC%D0%B8%D0%BB%D0%B8%D1%8F%3D%D0%9F%D0%B5%D1%82%D1%80%D0%BE%D0%B2"// The server will not understand such a URL


Remember the golden rule: encode each part of the URL separately or use URLComponents.



The correct approach: URLComponents



// ✅ Correct: use URLComponentsvar components = URLComponents()components.scheme = "https"components.host = "example.com"components.path = "/path"components.queryItems = [    URLQueryItem(name: "name", value: "Ivan & Petrov"),    URLQueryItem(name: "surname", value: "Ivanov")]

if let url = components.url { print(url.absoluteString) // "https://example.com/%D0%BF%D1%83%D1%82%D1%8C?name=%D0%98%D0%B2%D0%B0%D0%BD%20%26%20%D0%9F%D0%B5%D1%82%D1%80%D0%BE%D0%B2&%D1%84%D0%B0%D0%BC%D0%B8%D0%BB%D0%B8%D1%8F=%D0%98%D0%B2%D0%B0%D0%BD%D0%BE%D0%B2"}


URLComponents automatically applies the correct percent encoding for each component. This saves you headaches and makes the code cleaner.



Error #2: Ignoring queryItems in favor of manual string building



"Why do I need these components? I'll just concatenate the string with +". Sound familiar? And this leads to the second popular error. Manually building a query string is a direct path to bugs.



// ❌ Error: manual query string buildinglet name = "Ivan & Petrov"let query = "name=\\(name)&age=25"let urlString = "https://example.com?\\(query)"// Problem: the ampersand in the name will be interpreted as a parameter separator


Even if you replace spaces, you will forget about &, #, ? and other special characters. And if the parameter comes from the user? Expect injections and broken requests.



Solution: always use queryItems



// ✅ Correct: queryItems does all the work for youvar components = URLComponents(string: "https://example.com")!components.queryItems = [    URLQueryItem(name: "name", value: "Ivan & Petrov"),    URLQueryItem(name: "age", value: "25"),    URLQueryItem(name: "q", value: "Swift encode URL tutorial")]

if let url = components.url { print(url.absoluteStr

Blogs

Book Recommendations