gpt4 book ai didi

ios - 如何阻止 Alamofire 对 URL 参数进行编码

转载 作者:可可西里 更新时间:2023-11-01 01:25:06 24 4
gpt4 key购买 nike

我有一个这样的网址

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" instead "+"

但是,我需要留下来

"+"

如何使用 Alamofire 避免这种编码?

最佳答案

通常@rmaddy 在他的评论中是正确的。但我们可以关闭此编码作为一些有趣的练习。

我们需要为此使用自定义编码器。 Alamofire 支持任何实现 ParameterEncoding 协议(protocol)而不是 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())

关于ios - 如何阻止 Alamofire 对 URL 参数进行编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42010219/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com