首页 > 解决方案 > Swift 4 将参数添加到 URLRequest 完成处理程序

问题描述

我正在尝试从 Swift 4 中的 URLRequest 返回一些数据,为此我在我的函数签名中添加了一个完成处理程序,暂时只是使用 Bool。这是功能:

func getJson(completionHandler: @escaping (Bool) -> ()) {
    let jsonUrlString = "https://api.nytimes.com/svc/topstories/v1/business.json?api-key=f4bf2ee721031a344b84b0449cfdb589:1:73741808"
    guard let url = URL(string: jsonUrlString) else {return}

    URLSession.shared.dataTask(with: url) { (data, response, err) in
        guard let data = data, err == nil else {
            print(err!)
            return
        }

        do {
            let response = try
                JSONDecoder().decode(TopStoriesResponse.self, from: data)
            print(response.results)

            // Pass results into arrays (title, abstract, url, image)
            completionHandler(true)

            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        } catch let jsonErr {
            print("Error serializing JSON", jsonErr)
        }
    }.resume()
}

我这样称呼它viewDidLoad

getJson { (success) in
    print("Success")
}

没有任何东西打印到控制台,所以我想知道我是否正确使用了完成处理程序?但最终我想切换 Bool 并从请求中传递一些值,返回到我在视图控制器中拥有的数组中。

这些是我用来获取我想要的 JSON 片段的结构:

struct TopStoriesResponse: Decodable {
    let status: String
    let results: [Story]
}

struct Story: Decodable {
    let title: String
    let abstract: String
    let url: String
}

我最终试图用解析的 JSON 在我的视图控制器中填充这些数组,以便我可以将它们排列在表格视图中:

var headlines = [String]()
var abstracts = [String]()
var urls = [URL]()

编辑:完整代码,以防我在其他地方出错:https ://pastebin.com/r402GKej

标签: iosswift

解决方案


尝试从 ViewController 中单独创建结构TopStoriesResponseStory添加 Networking 结构以从 API 加载数据

struct TopStoriesResponse: Decodable {
    let status: String
    let copyright: String
    let num_results: Int
    let results: [Story]
}

struct Story: Decodable {
    let title: String
    let abstract: String
    let url: String
}

struct Networking {

    static func getJson(completionHandler: @escaping (Bool) -> ()) {

        let jsonUrlString = "https://api.nytimes.com/svc/topstories/v1/business.json?api-key=f4bf2ee721031a344b84b0449cfdb589:1:73741808"

        guard let url = URL(string: jsonUrlString) else {
            return
        }

        URLSession.shared.dataTask(with: url) { (data, response, error) in

            guard let data = data, error == nil else {
                print(error!.localizedDescription)
                return
            }

            do {
                let response: TopStoriesResponse = try JSONDecoder().decode(TopStoriesResponse.self, from: data)
                print(response.results.count)
                completionHandler(true)
            } catch {
                print(error.localizedDescription)
                completionHandler(false)
            }
        }.resume()
    }
}

现在尝试从 ViewController 调用 Networking.getJson

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        loadData()
    }

    func loadData() {
        Networking.getJson { (result) in
            print(result)
        }
    }
}

推荐阅读