5
5
// Created by Guilherme Souza on 23/04/24.
6
6
//
7
7
8
+ import Alamofire
8
9
import Foundation
9
10
10
11
#if canImport(FoundationNetworking)
@@ -16,15 +17,15 @@ import Foundation
16
17
17
18
extension Result {
18
19
package var value : Success ? {
19
- if case let . success( value) = self {
20
+ if case . success( let value) = self {
20
21
value
21
22
} else {
22
23
nil
23
24
}
24
25
}
25
26
26
27
package var error : Failure ? {
27
- if case let . failure( error) = self {
28
+ if case . failure( let error) = self {
28
29
error
29
30
} else {
30
31
nil
@@ -51,16 +52,20 @@ extension URL {
51
52
return
52
53
}
53
54
54
- let currentQueryItems = components . percentEncodedQueryItems ?? [ ]
55
+ let encoding = URLEncoding . queryString
55
56
56
- components. percentEncodedQueryItems =
57
- currentQueryItems
58
- + queryItems. map {
59
- URLQueryItem (
60
- name: escape ( $0. name) ,
61
- value: $0. value. map ( escape)
62
- )
57
+ func query( _ parameters: [ URLQueryItem ] ) -> String {
58
+ var components : [ ( String , String ) ] = [ ]
59
+
60
+ for param in parameters. sorted ( by: { $0. name < $1. name } ) {
61
+ components += encoding. queryComponents ( fromKey: param. name, value: param. value!)
63
62
}
63
+ return components. map { " \( $0) = \( $1) " } . joined ( separator: " & " )
64
+ }
65
+
66
+ let percentEncodedQuery =
67
+ ( components. percentEncodedQuery. map { $0 + " & " } ?? " " ) + query( queryItems)
68
+ components. percentEncodedQuery = percentEncodedQuery
64
69
65
70
if let newURL = components. url {
66
71
self = newURL
@@ -72,63 +77,4 @@ extension URL {
72
77
url. appendQueryItems ( queryItems)
73
78
return url
74
79
}
75
-
76
- // package mutating func appendOrUpdateQueryItems(_ queryItems: [URLQueryItem]) {
77
- // guard !queryItems.isEmpty else {
78
- // return
79
- // }
80
-
81
- // guard var components = URLComponents(url: self, resolvingAgainstBaseURL: false) else {
82
- // return
83
- // }
84
-
85
- // var currentQueryItems = components.percentEncodedQueryItems ?? []
86
-
87
- // for var queryItem in queryItems {
88
- // queryItem.name = escape(queryItem.name)
89
- // queryItem.value = queryItem.value.map(escape)
90
- // if let index = currentQueryItems.firstIndex(where: { $0.name == queryItem.name }) {
91
- // currentQueryItems[index] = queryItem
92
- // } else {
93
- // currentQueryItems.append(queryItem)
94
- // }
95
- // }
96
-
97
- // components.percentEncodedQueryItems = currentQueryItems
98
-
99
- // if let newURL = components.url {
100
- // self = newURL
101
- // }
102
- // }
103
-
104
- // package func appendingOrUpdatingQueryItems(_ queryItems: [URLQueryItem]) -> URL {
105
- // var url = self
106
- // url.appendOrUpdateQueryItems(queryItems)
107
- // return url
108
- // }
109
- }
110
-
111
- func escape( _ string: String ) -> String {
112
- string. addingPercentEncoding ( withAllowedCharacters: . sbURLQueryAllowed) ?? string
113
- }
114
-
115
- extension CharacterSet {
116
- /// Creates a CharacterSet from RFC 3986 allowed characters.
117
- ///
118
- /// RFC 3986 states that the following characters are "reserved" characters.
119
- ///
120
- /// - General Delimiters: ":", "#", "[", "]", "@", "?", "/"
121
- /// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
122
- ///
123
- /// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
124
- /// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
125
- /// should be percent-escaped in the query string.
126
- static let sbURLQueryAllowed : CharacterSet = {
127
- let generalDelimitersToEncode = " :#[]@ " // does not include "?" or "/" due to RFC 3986 - Section 3.4
128
- let subDelimitersToEncode = " !$&'()*+,;= "
129
- let encodableDelimiters = CharacterSet (
130
- charactersIn: " \( generalDelimitersToEncode) \( subDelimitersToEncode) " )
131
-
132
- return CharacterSet . urlQueryAllowed. subtracting ( encodableDelimiters)
133
- } ( )
134
80
}
0 commit comments