How to decode URL-encoded and URL query strings in Swift

2 Answers

0 votes
import Foundation

/// Decodes a URL-encoded string or query component.
/// Replaces '+' with spaces and decodes percent-encoded characters (%xx).
///
/// - Parameter encodedStr: The URL-encoded string.
/// - Returns: The fully decoded string, or the original if decoding fails.
func decodeUrlString(_ encodedStr: String) -> String {
    // Replace '+' with spaces first, as removingPercentEncoding treats '+' literally
    let normalized = encodedStr.replacingOccurrences(of: "+", with: " ")
    
    // removingPercentEncoding returns nil if the percent-encoding is malformed
    return normalized.removingPercentEncoding ?? encodedStr
}

// --- Program Execution ---
let sample1 = "Hello%20World%21%20Swift%20%26%20Web"
print("--- Example 1: Standard URL Encoding ---")
print("Encoded: \(sample1)")
print("Decoded: \(decodeUrlString(sample1))")

let sample2 = "Jane+Doe+from+New+York"
print("\n--- Example 2: Form Fragment Encoding ---")
print("Encoded: \(sample2)")
print("Decoded: \(decodeUrlString(sample2))")


/*
run:

--- Example 1: Standard URL Encoding ---
Encoded: Hello%20World%21%20Swift%20%26%20Web
Decoded: Hello World! Swift & Web

--- Example 2: Form Fragment Encoding ---
Encoded: Jane+Doe+from+New+York
Decoded: Jane Doe from New York

*/

 



answered 51 minutes ago by avibootz
0 votes
import Foundation

/// Parses and decodes a complete URL query string into a dictionary.
/// Groups duplicate keys into an array of values.
///
/// - Parameter queryString: The URL query string (with or without leading '?').
/// - Returns: A dictionary mapping keys to arrays of decoded values.
func parseAndDecodeQuery(queryString: String) -> [String: [String]] {
    // Ensure the query string has a leading '?' for URLComponents to parse it correctly
    let cleanQuery = queryString.hasPrefix("?") ? queryString : "?\(queryString)"
    let dummyURLString = "http://localhost/\(cleanQuery)"
    
    guard let components = URLComponents(string: dummyURLString),
          let queryItems = components.queryItems else {
        return [:]
    }
    
    var result: [String: [String]] = [:]
    
    for item in queryItems {
        // URLComponents automatically handles decoding and '+' to space conversion
        let value = item.value ?? ""
        result[item.name, default: []].append(value)
    }
    
    return result
}

// --- Program Execution ---
let fullQuery = "search=swift+tutorial&category=programming&tag=beginner&tag=ios"

print("--- Full Query String Parsing ---")
print("Original Query: \(fullQuery)")

let decodedDict = parseAndDecodeQuery(queryString: fullQuery)

print("Decoded Dictionary Result:")
for (key, values) in decodedDict {
    print("  \(key) -> \(values)")
}


/*
run:

--- Full Query String Parsing ---
Original Query: search=swift+tutorial&category=programming&tag=beginner&tag=ios
Decoded Dictionary Result:
  tag -> ["beginner", "ios"]
  category -> ["programming"]
  search -> ["swift+tutorial"]

*/

 



answered 50 minutes ago by avibootz
...