如何正确返回一个函数以使用 JSON 进行措辞?

Posted

技术标签:

【中文标题】如何正确返回一个函数以使用 JSON 进行措辞?【英文标题】:How can I return correctly a function for a phrasing with JSON? 【发布时间】:2018-10-21 16:28:36 【问题描述】:

最近我用CityBikes的API启动了一个项目,可以实时获取全球不同城市的共享单车站点数据(https://api.citybik.es/v2/)。 作为第一步,我提取了各种链接以获取接收各种信息所需的数据。 然后我创建了一个函数,extractStationData,它获取链接并将它们添加到“基本”链接,允许解析 JSON 并接收各种数据。我的问题就到这里了,因为我无法通过函数将之前获取的数据添加到链接中。 我怎样才能做到这一点?我是否必须通过返回来更改功能?

代码如下:

    let networksURL = "https://api.citybik.es/v2/networks/"
    guard let dataURL = URL(string: networksURL) else return

    URLSession.shared.dataTask(with: dataURL)  (data, response, err) in

        guard let data = data else return
        let dataAsString = String(data: data, encoding: .utf8)

    guard let blog = try? JSONDecoder().decode(Blog.self, from: data) else 
        print("Error: Couldn't decode data")
        return
    

    print("Networks link:")
    for article in blog.articles 
        print("- \(article.href)")
    

        func extractStationData() 
            for article in blog.articles 
                article.href
            
        

        let stationDataURL = "https://api.citybik.es\(extractStationData())"
        guard let newDataURL = URL(string: stationDataURL) else return

        URLSession.shared.dataTask(with: newDataURL)  (data, response, err) in

            guard let data = data else return
            let dataAsStringForStation = String(data: data, encoding: .utf8)

            guard let dataFromStation = try? JSONDecoder().decode(Datamain.self, from: data) else 
                print("Error: Couldn't decode station data")
                return
            

            print("data:")
            for something in dataFromStation.qwerty 
                print("- \(something.empty_slots)")
                print("- \(something.free_bikes)")
                print("- \(something.name)")
                print("- \(something.latitude)")
                print("- \(something.longitude)")

            

            .resume()
.resume()

【问题讨论】:

【参考方案1】:

您的代码无法运行。

您必须将两个任务分开,并使用DispatchGroup 在第二个任务中的网络请求完成时收到通知。

首先使用完成处理程序为主要任务创建一个函数,我省略了大部分代码以显示工作流程

func getMainData(completion: @escaping(Blog)->Void) 

  ...
  URLSession.shared.dataTask(with: dataURL)  (data, response, err) in 
     ...
     completion(blog)
  


根据完成处理程序中的主要数据调用该函数并执行网络请求

getMainData()  blog in 
    let group = DispatchGroup()
    for article in blog.articles 
        ...
        group.enter()
        // create newDataURL from article
        URLSession.shared.dataTask(with: newDataURL)  (data, response, err) in
           ...
            for something in dataFromStation.qwerty 
               print("- \(something.empty_slots)")
               print(" .... "
            
            group.leave()
        

    
    group.notify(queue: DispatchQueue.main) 
        print("finished")
    


但我建议(仅)在主视图控制器中加载主要数据,并在详细视图控制器中按需加载选定位置的数据。

【讨论】:

我不认为它们是两个独立的 API 调用,所以你不能让它们并行运行,如果你查看用于它的第二个请求参数是从第一个 API 的响应派生的,所以并行运行它们会导致第二个 API 一直失败 @SandeepBhandari 问题中的代码有点混乱。主要数据返回一个articles的数组,每篇文章都包含一个URL(href这个东西)来加载后续数据。最合理的控制方式是DispatchGroup 如果 OP 尝试分别为每篇文章加载数据,那么使用 DispatchGroup 绝对有意义,但在他的代码中,在这种情况下,他看起来像是在单个 API 调用中加载所有文章的数据如果我们使用 DispatchGroup 并没有太大区别,因为只有一个调用 :) 但你是对的,代码令人困惑,无法准确得出 OP 试图实现的目标 :) @SandeepBhandari 根据给定链接的 JSON,每篇文章显然有一个网络请求。 @SandeepBhandari 在 cmets 我经常写 JSON 很容易阅读。这不仅仅是一句话,这是真的?

以上是关于如何正确返回一个函数以使用 JSON 进行措辞?的主要内容,如果未能解决你的问题,请参考以下文章

使用类型保护缩小函数返回类型

如何使用firebase函数返回保存在firebase存储中的文件的json内容

如何正确解析 JSON 表以用于 Value 函数?

无法从从 sql 数据库读取的 javascript 函数中获取返回数组 [重复]

如何正确运用PHP json_encode函数进行中文转换

当 Api 返回响应时,如何以角度显示“登录失败。请重试”消息?