Swift 4向URLRequest完成处理程序添加参数

时间:2018-10-17 12:36:21

标签: ios swift

我正在尝试从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

1 个答案:

答案 0 :(得分:2)

尝试从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)
        }
    }
}