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 中分别创建结构 TopStoriesResponse
和 Story
并添加 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 Alamofire 将数据保存到核心数据时崩溃