在我的iPhone应用程序(在SWIFT中开发)中,我必须使用https服务(带参数)进行通信,并需要分析响应。
一切正常,但在某些情况下注意到它没有得到预期的结果...进一步分析我发现将服务器响应数据转换为字符串(NSData - > NSString)的问题......
1)。当我使用 UTF8 编码时,我得到nil作为转换后的String(responseString)
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
2)。但是使用 ASCII 编码它很好(获取正确的响应服务器提供)
let responseString = NSString(data: data, encoding: NSASCIIStringEncoding)
以下是我正在尝试的完整示例代码 ...
let myUrl = NSURL(string: "https://myurl.com/myservice.asp")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
request.timeoutInterval = 55.0
let postString = "paramone=\(para1)¶mtwo=\(para2)¶mthree=\(para3)"
// NOTE: Works ok with ASCII AND UTF8 both encoding types at this point...
// request.HTTPBody = postString.dataUsingEncoding(NSASCIIStringEncoding)
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
if (error != nil)
{
println("Error: \(error)")
println("Description: \(error.description)")
println("Domain : \(error.domain)")
println("Error code : \(error.code)")
}
else
{
//???? => ENCODING PROBLEM
// let responseString = NSString(data: data, encoding: NSASCIIStringEncoding)
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Response: \(responseString)")
}
}
task.resume()
我偶然发现其他几个POSTS解释了同样的问题...但不确定使用ASCII而不是UTF8是否合适......
此外,我无法理解响应包含'£'符号并且可以使用ASCII编码(尽管'''不是ASCII字符集),但不是UTF8。
想听听我是否遗漏了什么,或者最好的方式是什么......谢谢。
答案 0 :(得分:6)
NSASCIIStringEncoding
记录作为严格的7位编码
对于ASCII值0 .. 127.但是,实验表明何时
解码 NSData
到(NS)String
,它接受任意数据和
将字节0 .. 255解释为Unicode字符U + 0000 .. U + 00FF。
因此,当解码时,NSASCIIStringEncoding
的行为与...相同
NSISOLatin1StringEncoding
:
let bytes = (0 ..< 256).map { UInt8($0) }
let data = NSData(bytes: bytes, length: bytes.count)
let s1 = String(data: data, encoding: NSASCIIStringEncoding)!
let s2 = String(data: data, encoding: NSISOLatin1StringEncoding)!
print(s1 == s2) // true
这可以解释为什么像“£”这样的字符即使被正确解码也是如此 不在ASCII字符集中。
但请注意,这种行为(据我所知)没有记录,因此不应该依赖它。当编码时,这也不起作用
(NS)String
到NSData
:
let d1 = s1.dataUsingEncoding(NSASCIIStringEncoding) // nil
如果服务器发送带有Content-Type = charset=...
字段的HTTP响应标头,那么您可以自动检测编码,
见https://stackoverflow.com/a/32051684/1187415。
如果服务器未在HTTP响应中发送响应编码 标题然后你只能尝试不同的编码。经常使用 编码是
NSUTF8StringEncoding
用于UTF-8编码,NSWindowsCP1252StringEncoding
用于Windows-1252编码,NSISOLatin1StringEncoding
用于ISO-8859-1编码。还有一个NSString
方法可以检测使用过的方法
编码,但这要求您先将数据写入文件,
见Convert TXT File of Unknown Encoding to String。
答案 1 :(得分:4)
@JibW此代码将帮助您分析响应并易于理解......根据您的要求进行一些其他更改。!
let URL = NSURL(string: "Paste your url here")!
var request = NSMutableURLRequest(URL: URL)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.timeInterval = 55.0
var error: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: &error)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var data: NSData!
var response: NSURLResponse!
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
var httpResponse = response as! NSHTTPURLResponse
println("\(httpResponse.statusCode)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
if(err != nil) {
println(err!.localizedDescription)
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: '\(jsonStr)'")
}
else
{
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
var success = parseJSON["success"] as? Int
println("Succes: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: \(jsonStr)")
}
}
})
task.resume()