json - Swift - 解析 JSON 并检索数据

标签 json swift google-places-api

我正在 Xcode 上使用 Swift,并尝试解析 JSON 文件以检索有关附近商店的一些数据。 我的源代码如下:

import GooglePlaces

import SwiftyJSON

class Place {
    let name: String
    let coordinates: CLLocationCoordinate2D

    init(diction:[String : Any])
    {
        let json = JSON(diction)
        name = json["name"].stringValue //as! String

        let lat = json["geometry"]["location"]["lat"].doubleValue as CLLocationDegrees
        let long = json["geometry"]["location"]["lng"].doubleValue as CLLocationDegrees
        coordinates = CLLocationCoordinate2DMake(lat, long)
    }
}

class ViewController: UIViewController, MKMapViewDelegate, SceneLocationViewDelegate {


var urlString = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?"
        urlString += "&location=51.507514,-0.073603"
        urlString += "&radius=1500" //meters
        urlString += "&name=Specsavers"
        urlString += "&key=**************************" 

        guard let url = URL(string: urlString) else {return}
        var places = [Place]()

        var request = URLRequest(url:url)
        request.httpMethod = "GET"

        let task = URLSession.shared.dataTask(with: request as URLRequest) {
            data, response, error in
            print("HEREurlSession")
            if let content = data {
                do {
                    let json = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
                    print(json) // json results are printed fine here
                    if let results = json["results"] as? [[String : Any]] {
                        for place in results {
                            places.append(Place(diction: place))
                        }

                    }
                    else {
                        print("return")
                    }

                }
                catch{

                }
            }
        }
        task.resume()

        let size = places.count
        print("HERE: ", size)

}

构建成功,但输出为 size = 0,这意味着我没有检索数据,并且变量 places 为空。 我不知道它是否完全相关,但我收到以下警告:Cast from 'MDLMaterialProperty?!'对于 if let results = json["results"] as? 行,不相关类型“[[String : Any]]”总是失败 [[String : Any]] 在我的源代码中。

为什么我没有正确解析 JSON 文件并且没有检索到我想要的数据?

最佳答案

URLSession.shared.dataTask(with:) 是异步的。这意味着,它在后台运行。您正在执行

let size = places.count
print("HERE: ", size)

dataTask仍在工作时。

相反,您应该在完成处理程序中使用您的结果:

    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in
        print("HEREurlSession")
        if let content = data {
            do {
                let json = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
                                    print(json)
                if let results = json["results"] as? [[String : Any]] {
                    for place in results {
                        places.append(Place(diction: place))
                    }

                }
                else {
                    print("return")
                }

            }
            catch{

            }
        }

        // Use your result here
        let size = places.count
        useResultSize(size)

    }
    task.resume()

    func useResultSize(_ size: Int) {
        // Use your result here
        print("HERE: ", size)
    }

更新

看来您缺少异步执行的实际含义。让我尝试解释一下。

让我们在代码中标记执行顺序:

enter image description here

首先,执行代码的红色部分。程序从顶部开始执行,然后移动到底部红色框,只有在此之后(一旦网络请求完成)才执行绿色部分。

这意味着,您只能在代码的绿色部分使用网络请求的结果。在绿色部分之外,不保证结果可用。

如果您遵循我最初的建议,那么一切都会正常。请在我的 Playground 中查看成功执行情况:

enter image description here

关于json - Swift - 解析 JSON 并检索数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48077658/

相关文章:

ios - 当我在 Swift 中使用 PHAsset 时,我总是收到内存警告

ios - 以编程方式在场景之间进行转换的问题

通过摘要发现城市中值得注意的旅游目的地的 API

c# - 如何使用 ado.net 从 mssql 中选择数据

javascript - 如何解析来自 extjs 代理的响应?

javascript - 无法通过ajax在jquery fullcalendar中设置动态数据

ios - ios13表格模式单元格无法识别暗模式更改?

php - Google API 中的评论

modal-dialog - 谷歌地方在 ionic 模式屏幕中不起作用

java - gson.fromJson 返回空值