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)
    }
}