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}