我有这样的网址
https://www.mysite/v1/search?N=4249847587+1798040122
我像那样使用Alamofire
Almofire.request(.GET, "https://www.mysite/v1/search", parameters: ["N","4249847587+1798040122"], encoding: .URL)
记录请求,我收到
https://www.mysite/v1/search?N=4249847587%2B1798040122
即
“%2B”而非“+”
但是,我需要留在
“+”
如何使用Alamofire避免编码?
答案 0 :(得分:1)
一般来说@rmaddy的评论是正确的。但我们可以将这种编码作为一些有趣的练习。
我们需要使用自定义编码器。 Alamofire支持任何实现ParameterEncoding
协议而不是encoding: .URL
的自定义编码器。
所以我们可以使用原始Alamofire代码库中的一些复制和粘贴代码并创建自定义编码器
public struct NOURLEncoding: ParameterEncoding {
//protocol implementation
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var urlRequest = try urlRequest.asURLRequest()
guard let parameters = parameters else { return urlRequest }
if HTTPMethod(rawValue: urlRequest.httpMethod ?? "GET") != nil {
guard let url = urlRequest.url else {
throw AFError.parameterEncodingFailed(reason: .missingURL)
}
if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty {
let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
urlComponents.percentEncodedQuery = percentEncodedQuery
urlRequest.url = urlComponents.url
}
}
return urlRequest
}
//append query parameters
private func query(_ parameters: [String: Any]) -> String {
var components: [(String, String)] = []
for key in parameters.keys.sorted(by: <) {
let value = parameters[key]!
components += queryComponents(fromKey: key, value: value)
}
return components.map { "\($0)=\($1)" }.joined(separator: "&")
}
//Alamofire logic for query components handling
public func queryComponents(fromKey key: String, value: Any) -> [(String, String)] {
var components: [(String, String)] = []
if let dictionary = value as? [String: Any] {
for (nestedKey, value) in dictionary {
components += queryComponents(fromKey: "\(key)[\(nestedKey)]", value: value)
}
} else if let array = value as? [Any] {
for value in array {
components += queryComponents(fromKey: "\(key)[]", value: value)
}
} else if let value = value as? NSNumber {
if value.isBool {
components.append((escape(key), escape((value.boolValue ? "1" : "0"))))
} else {
components.append((escape(key), escape("\(value)")))
}
} else if let bool = value as? Bool {
components.append((escape(key), escape((bool ? "1" : "0"))))
} else {
components.append((escape(key), escape("\(value)")))
}
return components
}
//escaping function where we can select symbols which we want to escape
//(I just removed + for example)
public func escape(_ string: String) -> String {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*,;="
var allowedCharacterSet = CharacterSet.urlQueryAllowed
allowedCharacterSet.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
var escaped = ""
escaped = string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string
return escaped
}
}
extension NSNumber {
fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) }
}
我不知道为什么它会有用。但是可以轻松添加自定义编码。现在您可以使用我们的新编码器
来使用Alamofire请求Alamofire.request("http://www.mysite/v1/search", method: .get, parameters: ["N": "4249847587+1798040122"], encoding: NOURLEncoding())
答案 1 :(得分:1)
虽然这个问题已经得到了回答,但对于那些刚接触并且可能是第一次使用Alamofire并面临问题的人来说。
下面,
baseUrl =&#34; https://www.baseUrl.com/&#34;,
path =&#34; user / anything / status?current = Single&#34; 这就是我所做的(Swift 3.0,Alamofire v4.4)
let completeUrl = baseUrl.appending(path)
let urlWithoutPercent = completeUrl.removingPercentEncoding
let finalUrl = URL(string: urlWithoutPercent!)
var URLRequest = Foundation.URLRequest(url: finalUrl!)
或强>
let wholeURL = baseUrl.appending(path)
let urlwithPercent = wholeURL.addingPercentEncoding( withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
var URLRequest = Foundation.URLRequest(url: URL(string: urlwithPercent!)!)
现在的故事是:
我的网址正在转换为以下内容:
https://www.baseUrl.com/user/anything/status的%3F 当前=单
响应即将到来403。 在网上搜索了大约4个小时之后,我找不到一个简单而小巧的修复方法。然后通过删除百分比编码解决了问题。 另外,这并不是@rmaddy在评论中所说的正确方法。
这适用于所有特殊字符编码,无论是问号,感叹号还是其他任何东西......
希望它有所帮助。