©️ OverlookArt

URL

修改 URL 的参数

对 URL 进行扩展

 1extension URL {
 2    func modifyURLParameters(newParameters: [String: String]) -> URL? {
 3        guard var urlComponents = URLComponents(string: self.absoluteString) else { return nil }
 4        // 检查是否包含 `/#/`,需要特殊处理 fragment 部分
 5        if let fragment = urlComponents.fragment {
 6            // 分离 `/#/` 的路径和查询部分
 7            var fragmentComponents = fragment.components(separatedBy: "?")
 8            let path = fragmentComponents[0]
 9
10            // 获取查询参数部分,或初始化为空
11            var queryItems: [URLQueryItem] = []
12            if fragmentComponents.count > 1, let query = fragmentComponents[1].removingPercentEncoding {
13                queryItems = URLComponents(string: "http://dummy?\(query)")?.queryItems ?? []
14            }
15            // 遍历需要修改的参数
16            for (key, newValue) in newParameters {
17                // 查找是否已有该参数
18                if let index = queryItems.firstIndex(where: { $0.name == key }) {
19                    // 修改已有参数的值
20                    queryItems[index].value = newValue
21                } else {
22                    // 如果没有,则追加新参数
23                    queryItems.append(URLQueryItem(name: key, value: newValue))
24                }
25            }
26            // 重新组装 fragment
27            let newQuery = queryItems.map { "\($0.name)=\($0.value ?? "")" }.joined(separator: "&")
28            fragmentComponents = [path]
29            if !newQuery.isEmpty {
30                fragmentComponents.append(newQuery)
31            }
32            urlComponents.fragment = fragmentComponents.joined(separator: "?")
33        } else {
34            // 普通 URL,不包含 `/#/`,直接修改查询参数
35            var queryItems = urlComponents.queryItems ?? []
36            for (key, newValue) in newParameters {
37                // 查找是否已有该参数
38                if let index = queryItems.firstIndex(where: { $0.name == key }) {
39                    // 修改已有参数的值
40                    queryItems[index].value = newValue
41                } else {
42                    // 如果没有,则追加新参数
43                    queryItems.append(URLQueryItem(name: key, value: newValue))
44                }
45            }
46            urlComponents.queryItems = queryItems
47        }        
48        return urlComponents.url
49    }
50}