【问题标题】:How to parse Google Distance Matrix API JSON in IOS SWIFT 3 the correct way如何以正确的方式在 IOS SWIFT 3 中解析 Google 距离矩阵 API JSON
【发布时间】:2017-07-03 07:06:17
【问题描述】:

为了快速正确解析多维 JSON 数组,我进行了很多搜索。从搜索结果中,我可以理解的是,它有点类似于 Android 中的 Retro-fit 解析。即为每个 json 响应创建一个解析类。如果我犯了错误,请原谅。我是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")

    }

此代码运行良好。但我知道这不是这样做的方法。

所以请帮帮我

我认为此代码稍后可能会出现一些错误。不太清楚

【问题讨论】:

    标签: ios json swift3 google-distancematrix-api


    【解决方案1】:

    最简单、最有效的方法是使用对象映射。像 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 映射到 Object:

    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

    【讨论】:

    • 我的问题是我们可以在没有任何其他库的帮助的情况下解析它吗?我的意思是像在android中一样?
    • 当然可以,但不如使用对象映射有效。你最终会得到很多 if/guard 语句和 for 循环,这会导致错误(就像你拥有的代码一样)。 :-)
    • 从 Swift 4 可以在没有其他库帮助的情况下解析 json。有可解码medium.com/swiftly-swift/…
    猜你喜欢
    • 2012-03-27
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多