Swift编码&在GET参数中

时间:2017-04-01 08:50:53

标签: ios swift urlencode nsstringencoding

我有一个简单的 GET 登录请求。用户名为银色,密码为 MOto& @ 10
我正在使用SwiftHttp框架来处理请求。在点击登录请求时,我总是得到错误的回复 然而,当在浏览器上点击登录请求URL(用服务器替换实际域)时,我得到了真实:
https://server/api/check-access/by-login-pass?_key=wlyOF7TM8Y3tn19KUdlq&login=silver&pass=MOto%26@10

密码中的& 编码有问题。虽然我用百分比编码取而代之。这是我的代码:

do {               
   let passwordString = self.convertSpecialCharacters(string: password.text!)
   print("%@", passwordString)
   let opt = try HTTP.GET(Constants.kLoginUrl, parameters: ["login": username.text!, "pass": passwordString])
   opt.start { response in
             if let err = response.error {
                 print("error: \(err.localizedDescription)")
                 return
             }

             print("opt finished: \(response.description)")
             self.parseLoginResponse(response.data)
}
} catch _ as NSError {

}  

这是 convertSpecialCharacters

func convertSpecialCharacters(string: String) -> String {
        var newString = string

        let arrayEncode = ["&", "<", ">", "\"", "'", "-", "..."]

        for (escaped_char) in arrayEncode {
            newString = newString.encode(escaped_char)
        }

        return newString
    } 

编码扩展名:

extension String {
        func encode(_ chars: String) -> String
        {
            let forbidden = CharacterSet(charactersIn: chars)
            return self.addingPercentEncoding(withAllowedCharacters: forbidden.inverted) ?? self
        }
    }

2 个答案:

答案 0 :(得分:5)

一种合适的方法是使用URLComponents处理所有百分比编码:

var urlComponents = URLComponents(string: "https://server/api/check-access/by-login-pass")!
let queryItems = [URLQueryItem(name:"_key", value:"wlyOF7TM8Y3tn19KUdlq"),
                  URLQueryItem(name:"login", value:"silver"),
                  URLQueryItem(name:"pass", value:"MOto&@10")]
urlComponents.queryItems = queryItems
let url = urlComponents.url

print(url) // "https://server/api/check-access/by-login-pass?_key=wlyOF7TM8Y3tn19KUdlq&login=silver&pass=MOto%26@10"

PS:我完全赞同luk2302的评论。

答案 1 :(得分:0)

我决定为我的GET请求完全定制,因为其他一切都不想工作并让我生气。我使用了不同的请求,比如从我们的服务器获取列表。登录是通过POST请求完成的,这更容易。

但是,坚持GET请求: 我需要像&#34; +&#34;和&#34; /&#34;编码... 首先,我无法得到&#34; +&#34;用&#34; stringByAddingPercentEncodingWithAllowedCharacters编码&#34;方法。 所以我为String建立了自己的扩展:

extension String 
{
    return CFURLCreateStringByAddingPercentEscapes(
      nil,
      self as CFString,
      nil,
      "!*'();:@&=+$,/?%#[]" as CFString,
      CFStringBuiltInEncodings.UTF8.rawValue
    ) as String
}

第二步是将此添加到我的网址以获取最终请求。我想使用URLQueryItems并使用url.query或url.queryItems将它们添加到url。不好意外:我已经正确编码的字符串再次被编码,每个&#34;%&#34;在它里面成了&#34;%25&#34;使它无效。 -.-

所以现在我将每个编码值附加到一个字符串,该字符串将被添加到url中。感觉不是很敏捷&#34;但好吧..

let someUrl = "https://example.com/bla/bla.json"
var queryString = ""
var index = 0

// dicParam is of type [String: AnyObject] with all needed keys and values for the query
for (key, value) in dicParam  
{
    let encodedValue = (value as! String).encodeUrl()
    if index != 0
    {
        queryString.append("&\(key)=\(encodedValue)")
    }
    else
    {
        queryString.append("?\(key)=\(encodedValue)")
    }

    index += 1
}

let url = URLComponents(string: someUrl + queryString)!

希望这可以帮助某人并节省几个小时:/

相关问题