Swift JSON 正在解析 - 无法访问 field/returns 无
Swift JSON Parsing - Unable to access field/returns nil
我正在使用 Google 的地理定位器 API 自动映射一些东西。它在请求中 returns 一个 JSON 字符串,但我在解析它时遇到了很多困难。我已经尝试过 Freddy 和 SwiftyJSON 之类的东西,但都无法提取我想要的字段。
这是我的代码示例:
func sendJsonRequest(ConnectionString: String,
HTTPMethod : HttpMethod = HttpMethod.Get,
JsonHeaders : [String : String] = [ : ],
JsonString: String = "") -> NSData? {
// create the request & response
let request = NSMutableURLRequest(URL: NSURL(string: ConnectionString)!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
// create some JSON data and configure the request
let jsonString = JsonString;
request.HTTPBody = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
// handle both get and post
request.HTTPMethod = HTTPMethod.rawValue
// we'll always be sending json so this is fine
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// add the headers. If there aren't any then that's ok
for item in JsonHeaders {
request.addValue(item.1, forHTTPHeaderField: item.0)
}
print("Request:")
print(request)
let session = NSURLSession.sharedSession()
var data : NSData?
var urlTask = session.dataTaskWithRequest(request) { (Data, Response, Error) in
data = Data
}
urlTask.resume()
while (data == nil) {
}
return data
}
// return the coordinates of a given location
func getCoordinates() -> Coordinates {
var result = Coordinates()
let ConnectionString = "https://maps.googleapis.com/maps/api/geocode/json?address=43201"
let jsondata = sendJsonRequest(ConnectionString)
let data = jsondata
let json = JSON(data!)
print(json)
return result
}
getCoordinates()
这是我从单独的 JSON 客户端获得的输出示例:
{
"results": [
{
"address_components": [
{
"long_name": "43201",
"short_name": "43201",
"types": [
"postal_code"
]
},
{
"long_name": "Columbus",
"short_name": "Columbus",
"types": [
"locality",
"political"
]
},
{
"long_name": "Franklin County",
"short_name": "Franklin County",
"types": [
"administrative_area_level_2",
"political"
]
},
{
"long_name": "Ohio",
"short_name": "OH",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "United States",
"short_name": "US",
"types": [
"country",
"political"
]
}
],
"formatted_address": "Columbus, OH 43201, USA",
"geometry": {
"bounds": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
},
"location": {
"lat": 39.9929821,
"lng": -83.00122100000002
},
"location_type": "APPROXIMATE",
"viewport": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
}
},
"place_id": "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo",
"types": [
"postal_code"
]
}
],
"status": "OK"
}
我正在尝试获取字段 results.geometry.location。使用 Freddy JSON 解析库,我能够获得结果字段,但无法访问几何字段。有人可以看看这个,看看我做错了什么吗? SwiftyJSON 甚至不让我解析 JSON.
这是一个 javascript 对象,您可以执行以下操作来检索信息
将结果赋给一个变量
var results = {
"results": [
{
"address_components": [
{
"long_name": "43201",
"short_name": "43201",
"types": [
"postal_code"
]
},
{
"long_name": "Columbus",
"short_name": "Columbus",
"types": [
"locality",
"political"
]
},
{
"long_name": "Franklin County",
"short_name": "Franklin County",
"types": [
"administrative_area_level_2",
"political"
]
},
{
"long_name": "Ohio",
"short_name": "OH",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "United States",
"short_name": "US",
"types": [
"country",
"political"
]
}
],
"formatted_address": "Columbus, OH 43201, USA",
"geometry": {
"bounds": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
},
"location": {
"lat": 39.9929821,
"lng": -83.00122100000002
},
"location_type": "APPROXIMATE",
"viewport": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
}
},
"place_id": "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo",
"types": [
"postal_code"
]
}
],
"status": "OK"
};
console.log(results); // you can see the object
Object {results: Array[1], status: "OK"}
console.log(results.results[0]); // Accessing the first object inside the array
Object {address_components: Array[5], formatted_address: "Columbus, OH 43201, USA", geometry: Object, place_id: "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo", types: Array[1]}
console.log(results.results[0].geometry); // Accessing the geometry object.
Object {bounds: Object, location: Object, location_type: "APPROXIMATE", viewport: Object}
你可以使用JSON.stringify来简化它。
在 dataTaskWithRequest
中作为参数传递的闭包是异步的,这意味着它可以立即调用或在给定网络条件的情况下调用。最好在 return void
的原始 sendJsonRequest
方法中传递一个闭包。调用 dataTaskWithResult
闭包后,您可以使用响应调用闭包。
就代码而言,它可能看起来像这样:
func sendJsonRequest(connectionString: String,
httpMethod : HttpMethod = HttpMethod.Get,
jsonHeaders : [String : String] = [ : ],
jsonString: String = "",
completion: (data: NSData?, error: NSError?) -> Void) {
… //Your code
var urlTask = session.dataTaskWithRequest(request) { (optionalData, optionalResponse, optionalError) in
NSOperationQueue.mainQueue().addOperation {
if let data = optionalData {
completion(data, nil)
}
else if let error = optionalError {
completion(nil, error)
}
}
}
urlTask.resume()
}
// return the coordinates of a given location
func getCoordinates(withCompletion completion: (Coordinates) -> Void) {
let connectionString = "https://maps.googleapis.com/maps/api/geocode/json?address=43201"
sendJsonRequest(connectionString: connectionString) {
(optionalData, optionalError) in
if let data = optionalData {
let json = JSON(data)
print(json)
//Do your conversion to Coordinates here
let coordinates = //?
completion(coordinates)
}
// Handle errors, etc…
}
}
注意一点,参数和变量都是小写的。只有 class 个名称应该大写。
我的代码可以与 Freddy JSON 库一起使用。这是我的新代码,以防有人遇到类似问题:
func getCoordinates(address: String) -> Coordinates {
var result = Coordinates()
let ConnectionString = _connectionUrl + address
let jsondata = sendJsonRequest(ConnectionString)
//print(json)
// returns a [string : AnyObject]
let data = jsondata
do {
let json = try JSON(data: data!)
let results = try json.array("results")[0]
let geometry = try results.dictionary("geometry")
print(geometry)
let location = geometry["location"]!
print(location)
let lat = try location.double("lat")
let lng = try location.double("lng")
result.Latitude = lat
result.Longitude = lng
} catch {
let nsError = error as NSError
print(nsError.localizedDescription)
}
}
我正在使用 Google 的地理定位器 API 自动映射一些东西。它在请求中 returns 一个 JSON 字符串,但我在解析它时遇到了很多困难。我已经尝试过 Freddy 和 SwiftyJSON 之类的东西,但都无法提取我想要的字段。
这是我的代码示例:
func sendJsonRequest(ConnectionString: String,
HTTPMethod : HttpMethod = HttpMethod.Get,
JsonHeaders : [String : String] = [ : ],
JsonString: String = "") -> NSData? {
// create the request & response
let request = NSMutableURLRequest(URL: NSURL(string: ConnectionString)!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
// create some JSON data and configure the request
let jsonString = JsonString;
request.HTTPBody = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
// handle both get and post
request.HTTPMethod = HTTPMethod.rawValue
// we'll always be sending json so this is fine
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// add the headers. If there aren't any then that's ok
for item in JsonHeaders {
request.addValue(item.1, forHTTPHeaderField: item.0)
}
print("Request:")
print(request)
let session = NSURLSession.sharedSession()
var data : NSData?
var urlTask = session.dataTaskWithRequest(request) { (Data, Response, Error) in
data = Data
}
urlTask.resume()
while (data == nil) {
}
return data
}
// return the coordinates of a given location
func getCoordinates() -> Coordinates {
var result = Coordinates()
let ConnectionString = "https://maps.googleapis.com/maps/api/geocode/json?address=43201"
let jsondata = sendJsonRequest(ConnectionString)
let data = jsondata
let json = JSON(data!)
print(json)
return result
}
getCoordinates()
这是我从单独的 JSON 客户端获得的输出示例:
{
"results": [
{
"address_components": [
{
"long_name": "43201",
"short_name": "43201",
"types": [
"postal_code"
]
},
{
"long_name": "Columbus",
"short_name": "Columbus",
"types": [
"locality",
"political"
]
},
{
"long_name": "Franklin County",
"short_name": "Franklin County",
"types": [
"administrative_area_level_2",
"political"
]
},
{
"long_name": "Ohio",
"short_name": "OH",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "United States",
"short_name": "US",
"types": [
"country",
"political"
]
}
],
"formatted_address": "Columbus, OH 43201, USA",
"geometry": {
"bounds": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
},
"location": {
"lat": 39.9929821,
"lng": -83.00122100000002
},
"location_type": "APPROXIMATE",
"viewport": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
}
},
"place_id": "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo",
"types": [
"postal_code"
]
}
],
"status": "OK"
}
我正在尝试获取字段 results.geometry.location。使用 Freddy JSON 解析库,我能够获得结果字段,但无法访问几何字段。有人可以看看这个,看看我做错了什么吗? SwiftyJSON 甚至不让我解析 JSON.
这是一个 javascript 对象,您可以执行以下操作来检索信息
将结果赋给一个变量
var results = {
"results": [
{
"address_components": [
{
"long_name": "43201",
"short_name": "43201",
"types": [
"postal_code"
]
},
{
"long_name": "Columbus",
"short_name": "Columbus",
"types": [
"locality",
"political"
]
},
{
"long_name": "Franklin County",
"short_name": "Franklin County",
"types": [
"administrative_area_level_2",
"political"
]
},
{
"long_name": "Ohio",
"short_name": "OH",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "United States",
"short_name": "US",
"types": [
"country",
"political"
]
}
],
"formatted_address": "Columbus, OH 43201, USA",
"geometry": {
"bounds": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
},
"location": {
"lat": 39.9929821,
"lng": -83.00122100000002
},
"location_type": "APPROXIMATE",
"viewport": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
}
},
"place_id": "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo",
"types": [
"postal_code"
]
}
],
"status": "OK"
};
console.log(results); // you can see the object
Object {results: Array[1], status: "OK"}
console.log(results.results[0]); // Accessing the first object inside the array
Object {address_components: Array[5], formatted_address: "Columbus, OH 43201, USA", geometry: Object, place_id: "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo", types: Array[1]}
console.log(results.results[0].geometry); // Accessing the geometry object.
Object {bounds: Object, location: Object, location_type: "APPROXIMATE", viewport: Object}
你可以使用JSON.stringify来简化它。
在 dataTaskWithRequest
中作为参数传递的闭包是异步的,这意味着它可以立即调用或在给定网络条件的情况下调用。最好在 return void
的原始 sendJsonRequest
方法中传递一个闭包。调用 dataTaskWithResult
闭包后,您可以使用响应调用闭包。
就代码而言,它可能看起来像这样:
func sendJsonRequest(connectionString: String,
httpMethod : HttpMethod = HttpMethod.Get,
jsonHeaders : [String : String] = [ : ],
jsonString: String = "",
completion: (data: NSData?, error: NSError?) -> Void) {
… //Your code
var urlTask = session.dataTaskWithRequest(request) { (optionalData, optionalResponse, optionalError) in
NSOperationQueue.mainQueue().addOperation {
if let data = optionalData {
completion(data, nil)
}
else if let error = optionalError {
completion(nil, error)
}
}
}
urlTask.resume()
}
// return the coordinates of a given location
func getCoordinates(withCompletion completion: (Coordinates) -> Void) {
let connectionString = "https://maps.googleapis.com/maps/api/geocode/json?address=43201"
sendJsonRequest(connectionString: connectionString) {
(optionalData, optionalError) in
if let data = optionalData {
let json = JSON(data)
print(json)
//Do your conversion to Coordinates here
let coordinates = //?
completion(coordinates)
}
// Handle errors, etc…
}
}
注意一点,参数和变量都是小写的。只有 class 个名称应该大写。
我的代码可以与 Freddy JSON 库一起使用。这是我的新代码,以防有人遇到类似问题:
func getCoordinates(address: String) -> Coordinates {
var result = Coordinates()
let ConnectionString = _connectionUrl + address
let jsondata = sendJsonRequest(ConnectionString)
//print(json)
// returns a [string : AnyObject]
let data = jsondata
do {
let json = try JSON(data: data!)
let results = try json.array("results")[0]
let geometry = try results.dictionary("geometry")
print(geometry)
let location = geometry["location"]!
print(location)
let lat = try location.double("lat")
let lng = try location.double("lng")
result.Latitude = lat
result.Longitude = lng
} catch {
let nsError = error as NSError
print(nsError.localizedDescription)
}
}