如何解析 Google 距离矩阵 API JSON in IOS SWIFT 3 的正确方法
How to parse Google Distance Matrix API JSON in IOS SWIFT 3 the correct way
为了正确解析 swift 中的多维 JSON 数组,我进行了很多搜索。从搜索结果来看,我能理解的是它有点类似于 Android 中的 retro-fit 解析。即为每个 json 响应创建一个解析 class。如果我犯了错误,请原谅。我是 IOS swif 的新手。
这是距离矩阵 api json 为我的远程呼叫输出
{
"destination_addresses" : [ "My Destination" ],
"origin_addresses" : [
"My Source"
],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "23.3 km",
"value" : 23333 //lastly i take this
},
"duration" : {
"text" : "49 mins",
"value" : 2938
},
"status" : "OK" //then i check this
}
]
}
],
"status" : "OK" //first i check this
}
我是这样做的
这是我的 api 电话(工作正常)
func extract_Validate(jsonData:NSData)
{
var distInMeters = 0
var chkVarOne = "notOK"
let json1 = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue)
let data = json1!.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: false)
print(data!)
do{
print("Inside do")
let json = try JSONSerialization.jsonObject(with: jsonData as Data, options:.allowFragments) as! NSObject
if let dictionary = json as? [String: Any] {
print("inside dictionary ")
if let detailsDict = dictionary as? NSDictionary {
print("Parse Data")
for (key, value) in detailsDict {
print("Property: \"\(key as! String)\"")
if key as! String == "status" && value as! String == "OK"{
chkVarOne = "OK"
}
if chkVarOne == "OK"
{
if key as! String == "rows"
{
if let elementsDict = value as? NSDictionary {
for(keyEle, valueEle) in elementsDict{
}
}
if let elementsDict = value as? NSArray
{
if let array = elementsDict as? [Any] {
if let firstObject = array.first {
if let distanceSet = firstObject as? NSDictionary{
for(keyDis, valueDis) in distanceSet{
// print("Property: \"\(keyDis as! String)\"")
if keyDis as! String == "elements"
{
if let DistDict = valueDis as? NSDictionary {
for(keyDict, valueDict) in DistDict{
print("Property: \"\(keyDict as! String)\"")
}
}
if let DistDict = valueDis as? NSArray {
// print(DistDict)
if let distArr = DistDict as?[Any]{
if let frst = distArr.first{
//print(frst)
if let distOne = frst as? NSDictionary{
var checkvar = "notOK"
for(ketOneDis, valOneDis) in distOne{
// print("Property: \"\(ketOneDis as! String)\"", valOneDis)
if ketOneDis as! String == "status" && valOneDis as! String == "OK"{
checkvar = "OK"
}
if checkvar == "OK"
{
if ketOneDis as! String == "distance"
{
// print(valOneDis)
if let valtwoDis = valOneDis as? NSDictionary{
for(kDis, vDis) in valtwoDis{
// print("Property: \"\(kDis as! String)\"", vDis)
if kDis as! String == "value"{
distInMeters = vDis as! Int
}
}
if let valTwoDis = valOneDis as? NSArray{
print(valTwoDis)
}
}
}
}
}
}
}
}
}
}
//print(distanceSet,"rttgtgtgtgtgtgtg")
}
if let distSet = firstObject as? NSArray{
print(distSet,"dfdffddfdfdfd")
}
}
}
}
}
//let rows
}
}
} //ending here
}
}
}
catch{
print("error in JSONSerialization")
}
print(distInMeters," is the resulting value")
}
此代码运行良好。但我知道这不是办法。
所以请帮助我
我想这段代码后面可能会出现一些错误。不确定
最简单、最有效的方法是使用对象映射。像 Gloss (https://github.com/hkellaway/Gloss) 这样的东西就可以了。在您的情况下,您将拥有以下 类(对象):
回应
import Foundation
import Gloss
//MARK: - Response
public struct Response: Glossy {
public let destinationAddresses : [String]!
public let originAddresses : [String]!
public let rows : [Row]!
public let status : String!
//MARK: Decodable
public init?(json: JSON){
destinationAddresses = "destination_addresses" <~~ json
originAddresses = "origin_addresses" <~~ json
rows = "rows" <~~ json
status = "status" <~~ json
}
//MARK: Encodable
public func toJSON() -> JSON? {
return jsonify([
"destination_addresses" ~~> destinationAddresses,
"origin_addresses" ~~> originAddresses,
"rows" ~~> rows,
"status" ~~> status,
])
}
}
元素:
import Foundation
import Gloss
//MARK: - Element
public struct Element: Glossy {
public let distance : Distance!
public let duration : Distance!
public let status : String!
//MARK: Decodable
public init?(json: JSON){
distance = "distance" <~~ json
duration = "duration" <~~ json
status = "status" <~~ json
}
//MARK: Encodable
public func toJSON() -> JSON? {
return jsonify([
"distance" ~~> distance,
"duration" ~~> duration,
"status" ~~> status,
])
}
}
行:
import Foundation
import Gloss
//MARK: - Row
public struct Row: Glossy {
public let elements : [Element]!
//MARK: Decodable
public init?(json: JSON){
elements = "elements" <~~ json
}
//MARK: Encodable
public func toJSON() -> JSON? {
return jsonify([
"elements" ~~> elements,
])
}
}
距离:
import Foundation
import Gloss
//MARK: - Distance
public struct Distance: Glossy {
public let text : String!
public let value : Int!
//MARK: Decodable
public init?(json: JSON){
text = "text" <~~ json
value = "value" <~~ json
}
//MARK: Encodable
public func toJSON() -> JSON? {
return jsonify([
"text" ~~> text,
"value" ~~> value,
])
}
}
创建 类 后,通过执行以下操作将 JSON 映射到对象:
let jsonResponse = ..//Your JSON response
guard let distanceResponse = Response(json: jsonResponse) else {
// handle decoding failure here
}
//You can use the distanceResponse object here as an object and access it's values.
在本教程中了解有关对象映射的更多信息:https://www.raywenderlich.com/150322/swift-json-tutorial-2
为了正确解析 swift 中的多维 JSON 数组,我进行了很多搜索。从搜索结果来看,我能理解的是它有点类似于 Android 中的 retro-fit 解析。即为每个 json 响应创建一个解析 class。如果我犯了错误,请原谅。我是 IOS swif 的新手。
这是距离矩阵 api json 为我的远程呼叫输出
{
"destination_addresses" : [ "My Destination" ],
"origin_addresses" : [
"My Source"
],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "23.3 km",
"value" : 23333 //lastly i take this
},
"duration" : {
"text" : "49 mins",
"value" : 2938
},
"status" : "OK" //then i check this
}
]
}
],
"status" : "OK" //first i check this
}
我是这样做的
这是我的 api 电话(工作正常)
func extract_Validate(jsonData:NSData)
{
var distInMeters = 0
var chkVarOne = "notOK"
let json1 = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue)
let data = json1!.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: false)
print(data!)
do{
print("Inside do")
let json = try JSONSerialization.jsonObject(with: jsonData as Data, options:.allowFragments) as! NSObject
if let dictionary = json as? [String: Any] {
print("inside dictionary ")
if let detailsDict = dictionary as? NSDictionary {
print("Parse Data")
for (key, value) in detailsDict {
print("Property: \"\(key as! String)\"")
if key as! String == "status" && value as! String == "OK"{
chkVarOne = "OK"
}
if chkVarOne == "OK"
{
if key as! String == "rows"
{
if let elementsDict = value as? NSDictionary {
for(keyEle, valueEle) in elementsDict{
}
}
if let elementsDict = value as? NSArray
{
if let array = elementsDict as? [Any] {
if let firstObject = array.first {
if let distanceSet = firstObject as? NSDictionary{
for(keyDis, valueDis) in distanceSet{
// print("Property: \"\(keyDis as! String)\"")
if keyDis as! String == "elements"
{
if let DistDict = valueDis as? NSDictionary {
for(keyDict, valueDict) in DistDict{
print("Property: \"\(keyDict as! String)\"")
}
}
if let DistDict = valueDis as? NSArray {
// print(DistDict)
if let distArr = DistDict as?[Any]{
if let frst = distArr.first{
//print(frst)
if let distOne = frst as? NSDictionary{
var checkvar = "notOK"
for(ketOneDis, valOneDis) in distOne{
// print("Property: \"\(ketOneDis as! String)\"", valOneDis)
if ketOneDis as! String == "status" && valOneDis as! String == "OK"{
checkvar = "OK"
}
if checkvar == "OK"
{
if ketOneDis as! String == "distance"
{
// print(valOneDis)
if let valtwoDis = valOneDis as? NSDictionary{
for(kDis, vDis) in valtwoDis{
// print("Property: \"\(kDis as! String)\"", vDis)
if kDis as! String == "value"{
distInMeters = vDis as! Int
}
}
if let valTwoDis = valOneDis as? NSArray{
print(valTwoDis)
}
}
}
}
}
}
}
}
}
}
//print(distanceSet,"rttgtgtgtgtgtgtg")
}
if let distSet = firstObject as? NSArray{
print(distSet,"dfdffddfdfdfd")
}
}
}
}
}
//let rows
}
}
} //ending here
}
}
}
catch{
print("error in JSONSerialization")
}
print(distInMeters," is the resulting value")
}
此代码运行良好。但我知道这不是办法。
所以请帮助我
我想这段代码后面可能会出现一些错误。不确定
最简单、最有效的方法是使用对象映射。像 Gloss (https://github.com/hkellaway/Gloss) 这样的东西就可以了。在您的情况下,您将拥有以下 类(对象):
回应
import Foundation
import Gloss
//MARK: - Response
public struct Response: Glossy {
public let destinationAddresses : [String]!
public let originAddresses : [String]!
public let rows : [Row]!
public let status : String!
//MARK: Decodable
public init?(json: JSON){
destinationAddresses = "destination_addresses" <~~ json
originAddresses = "origin_addresses" <~~ json
rows = "rows" <~~ json
status = "status" <~~ json
}
//MARK: Encodable
public func toJSON() -> JSON? {
return jsonify([
"destination_addresses" ~~> destinationAddresses,
"origin_addresses" ~~> originAddresses,
"rows" ~~> rows,
"status" ~~> status,
])
}
}
元素:
import Foundation
import Gloss
//MARK: - Element
public struct Element: Glossy {
public let distance : Distance!
public let duration : Distance!
public let status : String!
//MARK: Decodable
public init?(json: JSON){
distance = "distance" <~~ json
duration = "duration" <~~ json
status = "status" <~~ json
}
//MARK: Encodable
public func toJSON() -> JSON? {
return jsonify([
"distance" ~~> distance,
"duration" ~~> duration,
"status" ~~> status,
])
}
}
行:
import Foundation
import Gloss
//MARK: - Row
public struct Row: Glossy {
public let elements : [Element]!
//MARK: Decodable
public init?(json: JSON){
elements = "elements" <~~ json
}
//MARK: Encodable
public func toJSON() -> JSON? {
return jsonify([
"elements" ~~> elements,
])
}
}
距离:
import Foundation
import Gloss
//MARK: - Distance
public struct Distance: Glossy {
public let text : String!
public let value : Int!
//MARK: Decodable
public init?(json: JSON){
text = "text" <~~ json
value = "value" <~~ json
}
//MARK: Encodable
public func toJSON() -> JSON? {
return jsonify([
"text" ~~> text,
"value" ~~> value,
])
}
}
创建 类 后,通过执行以下操作将 JSON 映射到对象:
let jsonResponse = ..//Your JSON response
guard let distanceResponse = Response(json: jsonResponse) else {
// handle decoding failure here
}
//You can use the distanceResponse object here as an object and access it's values.
在本教程中了解有关对象映射的更多信息:https://www.raywenderlich.com/150322/swift-json-tutorial-2