我使用google places api来获取经度和纬度,但无法解析字典。我正在使用以下代码
let lat = ((((dic["results"] as! AnyObject).value(forKey: "geometry") as AnyObject).value(forKey: "location") as AnyObject).value(forKey: "lat") as AnyObject).object(0) as! Double
错误:无法调用非功能类型的值'Any?!'
我还检查过nsdictionary而不是Anyobject但是没有用。 任何人都可以知道如何正确地从上面的代码中获取lat。
回应:
{
results = (
{
"address_components" = (
{
"long_name" = Palermo;
"short_name" = Palermo;
types = (
locality,
political
);
},
{
"long_name" = "Province of Palermo";
"short_name" = PA;
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = Sicily;
"short_name" = Sicily;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Italy;
"short_name" = IT;
types = (
country,
political
);
}
);
"formatted_address" = "Palermo, Italy";
geometry = {
bounds = {
northeast = {
lat = "38.219548";
lng = "13.4471566";
};
southwest = {
lat = "38.0615392";
lng = "13.2674205";
};
};
location = {
lat = "38.1156879";
lng = "13.3612671";
};
"location_type" = APPROXIMATE;
viewport = {
northeast = {
lat = "38.2194316";
lng = "13.4471566";
};
southwest = {
lat = "38.0615392";
lng = "13.2674205";
};
};
};
"place_id" = ChIJmdBOgcnoGRMRgNg7IywECwo;
types = (
locality,
political
);
}
);
status = OK;
}
答案 0 :(得分:7)
您必须分多步解析JSON,为清楚起见,我建议使用类型别名:
typealias JSONDictionary = [String:Any]
let results = dic["results"] as? [JSONDictionary] {
for result in results {
if let geometry = result["geometry"] as? JSONDictionary,
let location = geometry["location"] as? JSONDictionary {
if let lat = location["lat"] as? Double,
let lng = location["lng"] as? Double {
print(lat, lng)
}
}
}
}
Swift中的一些规则:
NSDictionary
/ NSArray
。[String:Any]
,是JSON数组[[String:Any]]
。Any
类型。答案 1 :(得分:4)
Kristijan的答案有些正确,但它忽略了许多重要的语法和可选的类型转换。假设您的代码中某处正在进行实际的API调用:
class SomeClass {
func getLocationData() {
//do your api call stuff here and get "result"
let location: Location? = Location(json: result as? [String:Any])
}
}
您可以通过某种方式处理响应,可能使用结构:
struct Location {
var lat: Double
var long: Double
init(lat: Double, long: Double) {
self.lat = lat
self.long = long
}
init?(json: [String:Any]?) {
guard let results = json?["results"] as? [Any],
let first = results[0] as? [String:Any],
let geometry = first["geometry"] as? [String:Any],
let location = geometry["location"] as? [String:Any],
let latitude = location["lat"] as? Double,
let longitude = location["lng"] as? Double else {
return nil
}
self.lat = latitude
self.long = longitude
}
}
struct initializer中的一点是使用条件展开来将JSON响应对象的各个成员类型转换为适当的类型。
请注意,根据您从API接收的实际JSON对象,这可能会有很大差异。除了您已经尝试编写以解析它的Swift代码之外,如果您可以在原始文本中发布实际的JSON响应将会很有帮助。我的回复会根据您提供的信息做到最好。如果您从API响应中提供原始JSON对象,我可能会写一些更有信心的东西。
编辑:以下是Playground代码段,用于检索和解析Google Places API中的结果
import PlaygroundSupport
import Foundation
PlaygroundPage.current.needsIndefiniteExecution = true
struct Location {
var lat: Double
var long: Double
init(lat: Double, long: Double) {
self.lat = lat
self.long = long
}
init?(json: [String:Any]?) {
guard let results = json?["results"] as? [Any],
let first = results[0] as? [String:Any],
let geometry = first["geometry"] as? [String:Any],
let location = geometry["location"] as? [String:Any],
let latitude = location["lat"] as? Double,
let longitude = location["lng"] as? Double else {
return nil
}
self.lat = latitude
self.long = longitude
}
}
func getLocationData() {
let base = "https://maps.googleapis.com/maps/api/geocode/json"
let args = [
"address=%50%61%6C%65%72%6D%6F%2C%20%50%72%6F%76%69%6E%63%65%20%6F%66%20%50%61%6C%65%72%6D%6F%2C%20%49%74%61%6C%79",
"sensor=false",
]
let urlStr = "\(base)?\(args.joined(separator: "&"))"
guard let url = URL(string: urlStr) else { return }
var request = URLRequest(url: url)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request,
completionHandler: { (data, response, error) -> Void in
guard let jsonData = data else { return }
if let jsonResult = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as? [String:Any] {
let location: Location? = Location(json: jsonResult)
print("Location: \(location?.lat), \(location?.long)")
}
}
).resume()
}
getLocationData()
答案 2 :(得分:0)
let geometry = = item["geometry"] as NSArray
let location = geometry["location"] as Dictionary
let latitude = location["lat"] as Double
let longitude = location["long"] as Double
试试这个,它从头开始,所以我不记得它100%正确,但你有几何数组内的位置字典和内部位置有lat / long参数。