解析提取 JSON 到 Swift 中的字典 3

Parsing fetched JSON to dictionary in Swift 3

在我的应用中,用户有时会提供电影名称。控制器将从 OMDB 获取有关电影的更多信息并存储它。我 运行 遇到了将 JSON 从 url 转换成字典的问题。这是我的代码:

@IBAction func addMovieButtonPressed(_ sender: Any) {
    // get title from the text field and prepare it for insertion into the url
    let movieTitle = movieTitleField.text!.replacingOccurrences(of: " ", with: "+")
    // get data for the movie the user named
    let movieData = getMovieData(movieTitle: movieTitle)
    // debug print statement
    print(movieData)
    // reset text field for possible new entry
    movieTitleField.text = ""
}

// function that retrieves the info about the movie and converts it to a dictionary
private func getMovieData(movieTitle: String) -> [String: Any] {

    // declare a dictionary for the parsed JSON to go in
    var movieData = [String: Any]()

    // prepare the url in proper type
    let url = URL(string: "http://www.omdbapi.com/?t=\(movieTitle)")

    // get the JSON from OMDB, parse it and store it into movieData
    URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
        guard let data = data, error == nil else { return }
        do {
            movieData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]
        } catch let error as NSError {
            print(error)
        }
    }).resume()

    // return the data
    return movieData
}

我已经尝试了在 Whosebug 上找到的 URLSession 部分的许多变体,我知道数据已成功获取:

但是我不知道如何正确地获取它并将其变成我可以在我的应用程序的其余部分中使用的字典。 IBAction 函数中的打印语句总是 returns 一个空字典。

我做错了什么?

查看完成块和异步函数。您的 getMovieData 在调用数据任务的完成处理程序之前返回。

您的函数将调用传入的完成块,而不是返回,并且应更改为:

private func getMovieData(movieTitle: String, completion: @escaping ([String:Any]) -> Void) {

    // declare a dictionary for the parsed JSON to go in
    var movieData = [String: Any]()

    // prepare the url in proper type
    let url = URL(string: "http://www.omdbapi.com/?t=\(movieTitle)")

    // get the JSON from OMDB, parse it and store it into movieData
    URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
        guard let data = data, error == nil else { return }
        do {
            movieData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]
            completion(movieData)
        } catch let error as NSError {
            print(error)
        }
    }).resume()
}