xcode 解析 JSON Swift
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26551029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parsing JSON Swift
提问by rocket101
I am working on an app that displays the live Bitcoin price. I am using 2 APIs to do this - one plaintext, and one JSON. I am having a bit of trouble with the JSON API.
我正在开发一个显示实时比特币价格的应用程序。我使用 2 个 API 来执行此操作 - 一个纯文本和一个 JSON。我在使用 JSON API 时遇到了一些麻烦。
Here's a bit of my Swift code
这是我的一些 Swift 代码
func BTCFallback(){
var string2 = currencySelector.currentTitle
var url = NSURL(string:"https://bitpay.com/api/rates/" + (string2)!)
var request = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:fallback)
var data = NSData(contentsOfURL:url);
let value = NSString(string: USD.text).doubleValue / NSString(data:data, encoding:NSUTF8StringEncoding).doubleValue
// Define JSON string
var JSONString = "\(data)"
// Get NSData using string
if let JSONData = JSONString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
// Parse JSONData into JSON object
var parsingError: NSError?
if let JSONObject = NSJSONSerialization.JSONObjectWithData(JSONData, options: nil, error: &parsingError) as? [String: AnyObject] {
// If the parsing was successful grab the rate object
var rateObject: AnyObject? = JSONObject["rate"]
// Make sure the rate object is the expected type
if let rate = rateObject as? Float {
println("rate is \(rate)")
BTC.text = "\(rate)"
}
} else {
// There was an error parsing the JSON data
println("Error parsing JSON: \(parsingError)")
BTC.text = "err1"
}
}
}
In the above code, currencySelector.currentTitle is equal to an ISO currency code, for instance USD. BTC.text is a UI element.
在上面的代码中,currencySelector.currentTitle 等于 ISO 货币代码,例如 USD。BTC.text 是一个 UI 元素。
The expected behavior is that the code will set the counterpart of "rate" as the text of BTC.text. In case this helps, the API returns something like {"code":"USD","name":"US Dollar","rate":376.71}. I would want, using the above example, to have BTC.text set to 376.71
预期的行为是代码将“rate”的对应项设置为 BTC.text 的文本。如果这有帮助,API 会返回类似 {"code":"USD","name":"US Dollar","rate":376.71} 的内容。我希望使用上面的示例将 BTC.text 设置为 376.71
Here's what's happening: the consoe gives the error
Error parsing JSON: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x16eb0f60 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})
这是正在发生的事情:控制台给出了错误
Error parsing JSON: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x16eb0f60 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})
What am I doing wrong? Thanks in advance!
我究竟做错了什么?提前致谢!
回答by zaph
It is all a matter of handling the returned data and de-serialization.
这完全是处理返回的数据和反序列化的问题。
Here is example code, note that the handling of Optionals should be better, this is just to demonstrate the basic code. For example purposes I used a simple synchronous web call.:
这里是示例代码,注意Optionals的处理应该更好,这只是为了演示基本代码。例如,我使用了一个简单的同步网络调用。:
var url: NSURL! = NSURL(string:"https://bitpay.com/api/rates/AUD")
var request = NSURLRequest(URL: url)
var response: NSURLResponse?
var error: NSError?
var data: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)
println("data: \(data)")
if let data: NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error) {
println("data: \(data)")
var parsingError: NSError?
if let rateDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parsingError) as NSDictionary? {
println("rateDictionary: \(rateDictionary)")
// If the parsing was successful grab the rate object
if var rateString: AnyObject = rateDictionary["rate"] {
println("rateString: \(rateString)")
// Make sure the rate object is the expected type
if let rate = rateString.floatValue {
println("rate is \(rate)")
}
}
}
}
Ouput:
输出:
data: Optional(7b22636f 6465223a 22415544 222c226e 616d6522 3a224175 73747261 6c69616e 20446f6c 6c617222 2c227261 7465223a 3430372e 39393137 7d) rateDictionary: { code = AUD; name = "Australian Dollar"; rate = "407.9917"; } rateString: 407.9917 rate is 407.992