将 JSON 从 AlamoFire/SwiftyJSON 转换为 Swift/Xcode 中的字典
Converting JSON from AlamoFire/SwiftyJSON to Dictionary in Swift/Xcode
我的脑袋要爆炸了:) - 我一直在尝试从我的服务器获取一个 JSON 字符串到一个字典值,但我无法让它工作。
我正在尝试获取(从我的服务器 - 这是动态的,我希望我的应用程序能够在需要时从服务器提取新数据):
{"1":"Location 1","2":"Location 2","3":"Location 3"}
使用 Swift 在 Xcode 中使用此词典:
var labels = [
1 : "Location 1",
2 : "Location 2",
3 : "Location 3"
]
这一定很简单,但我这辈子都想不通...
这是我的 Swift - 我可以用它从服务器中提取信息,但我无法像我需要的那样将它放入字典中
var postEndpoint: String = "http://www.myserver.net/app/campus.php"
Alamofire.request(.GET, postEndpoint)
.responseJSON { (request, response, data, error) in
if let anError = error
{
println("error")
println(error)
}
else if let data: AnyObject = data
{
let post = JSON(data)
println(post)
}
}
这导致:
{
"1" : "Location 1",
"2" : "Location 2",
"3" : "Location 3"
}
我使用它的最终结果是一个 iBeacon 实现,代码如下:
let knownBeacons = beacons.filter{ [=17=].proximity != CLProximity.Unknown }
if (knownBeacons.count > 0) {
let closestBeacon = knownBeacons[0] as CLBeacon
let locationID = post[closestBeacon.minor.integerValue]
self.locationLabel.text = locationID
self.view.backgroundColor = self.colors[closestBeacon.minor.integerValue]
}
我得到的错误是在 self.locationLabel.text = locationID 'JSON' is not convertible to 'String',当我使用静态变量标签字典时我没有得到这个错误。我是否试图错误地从服务器获取数据?我究竟做错了什么???我认为具有未声明类型的 var 标签允许 Swift 弄清楚它需要什么,我如何从 JSON 部分做同样的事情?
我通过反向工作解决了这个问题。我换了电话。我没有从服务器获取值字典,而是使用我已经从变量
获得的单个变量查询服务器
closestBeacon.minor.integerValue
然后从服务器获取我需要的字符串,这解决了我的问题。对服务器的调用次数仍然相同,因此没有增加额外的开销。有时候,您只需要跳出自己的思维定势。
如果有人能从另一个方向解决这个问题,我仍然很想知道它是如何工作的。
哦,你太接近了!
您的问题是您的 post
词典是 [String: String]
而不是您认为的 [Int: String]
。您有几种修复方法,但目前最简单的方法是执行以下操作:
let locationID = post[String(closestBeacon.minor.integerValue)]!
虽然这肯定有效,但更好的解决方案是将您的 post
转换为 [Int: String]
类型的字典,就像您在 responseJSON
闭包中期望的那样。这是它的工作原理。
let json = JSON(data)
var post = [Int: String]()
for (key, object) in json {
post[key.toInt()!] = object.stringValue
}
如果 key
或 object
无法分别转换为 Int
或 String
,您可能会想增加一些安全措施,但我会把它留给你。
如果 [String: String]
对任何人都足够,he/she 可以尝试以下代码:
let responseString = "{\"1\":\"Location 1\",\"2\":\"Location 2\",\"3\":\"Location 3\"}"
if let dataFromString = responseString.data(using: String.Encoding.utf8, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
var labels = json.dictionaryObject! as! [String: String]
print(labels)
}
结果是:
["2": "Location 2", "1": "Location 1", "3": "Location 3"]
.
您还需要递归检查内部 JSON
使用下面的函数转换成字典或数组
static func toDictionary(from: JSON) -> Any? {
if from.type == .array {
var array = [Any]()
for _i in 0..<from.count {
array.append(toDictionary(from: from[_i]) as Any)
}
return array
} else if from.type == .dictionary {
var dictionary = [String: Any]()
for (key, value) in from {
dictionary[key] = toDictionary(from: value)
}
return dictionary
} else {
return from.stringValue
}
}
我的脑袋要爆炸了:) - 我一直在尝试从我的服务器获取一个 JSON 字符串到一个字典值,但我无法让它工作。
我正在尝试获取(从我的服务器 - 这是动态的,我希望我的应用程序能够在需要时从服务器提取新数据):
{"1":"Location 1","2":"Location 2","3":"Location 3"}
使用 Swift 在 Xcode 中使用此词典:
var labels = [
1 : "Location 1",
2 : "Location 2",
3 : "Location 3"
]
这一定很简单,但我这辈子都想不通...
这是我的 Swift - 我可以用它从服务器中提取信息,但我无法像我需要的那样将它放入字典中
var postEndpoint: String = "http://www.myserver.net/app/campus.php"
Alamofire.request(.GET, postEndpoint)
.responseJSON { (request, response, data, error) in
if let anError = error
{
println("error")
println(error)
}
else if let data: AnyObject = data
{
let post = JSON(data)
println(post)
}
}
这导致:
{
"1" : "Location 1",
"2" : "Location 2",
"3" : "Location 3"
}
我使用它的最终结果是一个 iBeacon 实现,代码如下:
let knownBeacons = beacons.filter{ [=17=].proximity != CLProximity.Unknown }
if (knownBeacons.count > 0) {
let closestBeacon = knownBeacons[0] as CLBeacon
let locationID = post[closestBeacon.minor.integerValue]
self.locationLabel.text = locationID
self.view.backgroundColor = self.colors[closestBeacon.minor.integerValue]
}
我得到的错误是在 self.locationLabel.text = locationID 'JSON' is not convertible to 'String',当我使用静态变量标签字典时我没有得到这个错误。我是否试图错误地从服务器获取数据?我究竟做错了什么???我认为具有未声明类型的 var 标签允许 Swift 弄清楚它需要什么,我如何从 JSON 部分做同样的事情?
我通过反向工作解决了这个问题。我换了电话。我没有从服务器获取值字典,而是使用我已经从变量
获得的单个变量查询服务器closestBeacon.minor.integerValue
然后从服务器获取我需要的字符串,这解决了我的问题。对服务器的调用次数仍然相同,因此没有增加额外的开销。有时候,您只需要跳出自己的思维定势。
如果有人能从另一个方向解决这个问题,我仍然很想知道它是如何工作的。
哦,你太接近了!
您的问题是您的 post
词典是 [String: String]
而不是您认为的 [Int: String]
。您有几种修复方法,但目前最简单的方法是执行以下操作:
let locationID = post[String(closestBeacon.minor.integerValue)]!
虽然这肯定有效,但更好的解决方案是将您的 post
转换为 [Int: String]
类型的字典,就像您在 responseJSON
闭包中期望的那样。这是它的工作原理。
let json = JSON(data)
var post = [Int: String]()
for (key, object) in json {
post[key.toInt()!] = object.stringValue
}
如果 key
或 object
无法分别转换为 Int
或 String
,您可能会想增加一些安全措施,但我会把它留给你。
如果 [String: String]
对任何人都足够,he/she 可以尝试以下代码:
let responseString = "{\"1\":\"Location 1\",\"2\":\"Location 2\",\"3\":\"Location 3\"}"
if let dataFromString = responseString.data(using: String.Encoding.utf8, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
var labels = json.dictionaryObject! as! [String: String]
print(labels)
}
结果是:
["2": "Location 2", "1": "Location 1", "3": "Location 3"]
.
您还需要递归检查内部 JSON 使用下面的函数转换成字典或数组
static func toDictionary(from: JSON) -> Any? {
if from.type == .array {
var array = [Any]()
for _i in 0..<from.count {
array.append(toDictionary(from: from[_i]) as Any)
}
return array
} else if from.type == .dictionary {
var dictionary = [String: Any]()
for (key, value) in from {
dictionary[key] = toDictionary(from: value)
}
return dictionary
} else {
return from.stringValue
}
}