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

Posted

技术标签:

【中文标题】Swift 4 将参数添加到 URLRequest 完成处理程序【英文标题】:Swift 4 adding parameters to URLRequest completion handler 【发布时间】:2018-10-17 12:36:21 【问题描述】:

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

【问题讨论】:

print(response.results) 打印什么吗? 不,它没有 - 我把那个放错地方了吗? 您说“没有任何东西打印到控制台。”您的任何打印语句都没有向控制台显示任何内容?在创建 dataTask 之前尝试添加打印语句。如果只是您的完成处理程序没有打印,那是因为您只在成功情况下调用完成处理程序。在失败案例中,您应该使用 false 值调用它。 @KingTim 否,但它表明该代码永远不会被执行。所以我猜数据是空的。 @DuncanC 在数据任务之前添加打印语句也不打印任何内容。现在我真的很困惑......也没有错误打印 【参考方案1】:

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

【讨论】:

let response: Response = try JSONDecoder().decode(TopStoriesResponse.self, from: data)线上抛出错误Use of undeclared type 'Response' 尝试在 getJson 方法中将 Response 更改为 TopStoriesResponse 好吧,这似乎是我的表格视图的问题。我创建了一个新的 Xcode 项目(非 tableview),您的解决方案(以及我在初始帖子中的代码)可以将结果打印到控制台。不知道为什么表格视图搞砸了。但我最初的问题是如何将标题、摘要等从数据请求中取出并放入我设置的数组中。知道如何实现吗? 您可以在完成处理程序中返回 TopStoriesResponse,该处理程序具有包含所有故事的结果参数。您可以在表格视图中显示这些故事。如果您想创建单独的数组,那么您需要迭代故事并为标题、网址等创建这些数组。我认为您应该使用故事数组在单元格中显示 你的解决方案和我的初始代码只是从请求中得到response.results,换句话说,所有的标题、摘要和url一起。我如何将这些东西分开抓起来并放入我的牢房?我认为将它们安排到我的阵列中并从那里开始是最好的方法,但我对其他事情持开放态度。这是我的完整代码,因此您也可以查看表格视图方法:pastebin.com/r402GKej

以上是关于Swift 4 将参数添加到 URLRequest 完成处理程序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Alamofire 4 和 Swift 3 中设置方法、标题、参数

带参数的 Swift GET 请求

尝试从响应 Swift Alamofire 将数据保存到核心数据时崩溃

我可以在 Swift 中使用 IP 地址构建 URLRequest 吗?

Swift 5:简单的字符串 URLRequest

错误:“模式无法匹配 'URLRequest' 类型的值”在 swift 中