从 Swift 3 和 Xcode 8 中的嵌套字典中获取值的问题
Problems with getting values out of nested dictionary in Swift 3 and Xcode 8
我用这个解析 JSON :
let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers)
得到如下嵌套字典
{ response = { GeoObjectCollection = { featureMember =
(
{ GeoObject = { Point = { pos = "40.275713 59.943413"; }; }; },
{ GeoObject = { Point = { pos = "40.273162 59.944292"; }; }; }
);
};
};
}
我正在尝试从此字典中获取坐标值并将它们保存到新的 latutudeString 和 longitudeString 变量中
在 Xcode 8 GM 之前,我使用此代码对我有用:
if let jsonCoordinatesString: String = dictionary["response"]!!["GeoObjectCollection"]!!["featureMember"]!![0]["GeoObject"]!!["Point"]!!["pos"]!! as? String {
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
但是因为我已经安装了 Xcode 8 GM,所以我收到一个错误:
Type Any has no Subscript members
如何用 Xcode 8 修复它 Swift 3 ?我读过我可以转换它,但不知道如何使用我在 swift 3 中的嵌套字典和最新的 Xcode。我读过 但它对我的情况确实没有帮助。
问题是你没有指定dictionary
对象的类型,需要像这样明确指定dictionary
对象的类型为Dictionary
let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as! [String: Any]
if let response = dictionary["response"] as? [String: Any],
let geoObjectCollection = response["GeoObjectCollection"] as? [String: Any],
let featureMember = geoObjectCollection["featureMember"] as? [[String: Any]] {
if let geoObject = featureMember[0]["GeoObject"] as? [String: Any],
let point = geoObject["Point"] as? [String: String] {
let latLongArray = point["pos"].components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
}
您的 JSON 数据在 Swift 中具有此类型:
[String: [String: [String: [[String: [String: [String: String]]]]]]]
我会避免使用这种嵌套太深的类型,但如果你敢用,你可以这样写:
enum MyError: Error {
case invalidStructure
}
do {
guard let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as? [String: [String: [String: [[String: [String: [String: String]]]]]]] else {
throw MyError.invalidStructure
}
if let jsonCoordinatesString: String = dictionary["response"]?["GeoObjectCollection"]?["featureMember"]?[0]["GeoObject"]?["Point"]?["pos"] {
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
} catch let error {
print(error)
}
但您可能隐藏了 JSON 数据的一些不相关成员,这可能会破坏此 as?
转换。
所以,你可以一步一步来,在某些情况下 "need to" in Swift 3,像这样:
do {
guard let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as? [String: AnyObject] else {
throw MyError.invalidStructure
}
if
let response = dictionary["response"] as? [String: AnyObject],
let geoObjectCollection = response["GeoObjectCollection"] as? [String: AnyObject],
let featureMember = geoObjectCollection["featureMember"] as? [[String: AnyObject]],
!featureMember.isEmpty,
let geoObject = featureMember[0]["GeoObject"] as? [String: AnyObject],
let point = geoObject["Point"] as? [String: AnyObject],
let jsonCoordinatesString = point["pos"] as? String
{
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
} catch let error {
print(error)
}
(let
s 对于 Swift 3 中的每个可选绑定都是强制性的。如果您愿意,您可以将所有 AnyObject
s 更改为 Any
s。 )
我用这个解析 JSON :
let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers)
得到如下嵌套字典
{ response = { GeoObjectCollection = { featureMember =
(
{ GeoObject = { Point = { pos = "40.275713 59.943413"; }; }; },
{ GeoObject = { Point = { pos = "40.273162 59.944292"; }; }; }
);
};
};
}
我正在尝试从此字典中获取坐标值并将它们保存到新的 latutudeString 和 longitudeString 变量中
在 Xcode 8 GM 之前,我使用此代码对我有用:
if let jsonCoordinatesString: String = dictionary["response"]!!["GeoObjectCollection"]!!["featureMember"]!![0]["GeoObject"]!!["Point"]!!["pos"]!! as? String {
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
但是因为我已经安装了 Xcode 8 GM,所以我收到一个错误:
Type Any has no Subscript members
如何用 Xcode 8 修复它 Swift 3 ?我读过我可以转换它,但不知道如何使用我在 swift 3 中的嵌套字典和最新的 Xcode。我读过
问题是你没有指定dictionary
对象的类型,需要像这样明确指定dictionary
对象的类型为Dictionary
let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as! [String: Any]
if let response = dictionary["response"] as? [String: Any],
let geoObjectCollection = response["GeoObjectCollection"] as? [String: Any],
let featureMember = geoObjectCollection["featureMember"] as? [[String: Any]] {
if let geoObject = featureMember[0]["GeoObject"] as? [String: Any],
let point = geoObject["Point"] as? [String: String] {
let latLongArray = point["pos"].components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
}
您的 JSON 数据在 Swift 中具有此类型:
[String: [String: [String: [[String: [String: [String: String]]]]]]]
我会避免使用这种嵌套太深的类型,但如果你敢用,你可以这样写:
enum MyError: Error {
case invalidStructure
}
do {
guard let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as? [String: [String: [String: [[String: [String: [String: String]]]]]]] else {
throw MyError.invalidStructure
}
if let jsonCoordinatesString: String = dictionary["response"]?["GeoObjectCollection"]?["featureMember"]?[0]["GeoObject"]?["Point"]?["pos"] {
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
} catch let error {
print(error)
}
但您可能隐藏了 JSON 数据的一些不相关成员,这可能会破坏此 as?
转换。
所以,你可以一步一步来,在某些情况下 "need to" in Swift 3,像这样:
do {
guard let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as? [String: AnyObject] else {
throw MyError.invalidStructure
}
if
let response = dictionary["response"] as? [String: AnyObject],
let geoObjectCollection = response["GeoObjectCollection"] as? [String: AnyObject],
let featureMember = geoObjectCollection["featureMember"] as? [[String: AnyObject]],
!featureMember.isEmpty,
let geoObject = featureMember[0]["GeoObject"] as? [String: AnyObject],
let point = geoObject["Point"] as? [String: AnyObject],
let jsonCoordinatesString = point["pos"] as? String
{
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
} catch let error {
print(error)
}
(let
s 对于 Swift 3 中的每个可选绑定都是强制性的。如果您愿意,您可以将所有 AnyObject
s 更改为 Any
s。 )