如何解析 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 电话(工作正常)

http://maps.googleapis.com/maps/api/distancematrix/json?origins=latitude,longitude&destinations=latitude,longitude&mode=driving&language=en-EN&sensor=false

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