【问题标题】:Make a Swift 5 function with completionHandler to print JSON data使用 completionHandler 制作一个 Swift 5 函数来打印 JSON 数据
【发布时间】:2020-05-03 04:53:26
【问题描述】:

我有以下 Swift 5 函数在我的服务器上调用 PHP 脚本:

func getJSONdata(fileName:String, completion: (_ json:JSON)->()) {
        let session = URLSession(configuration: .ephemeral)
        var jsonData = JSON()

        let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
        var request = URLRequest(url:myUrl!)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        DispatchQueue.main.async {
            let task = session.dataTask(with: request) { (data, response, error)  in
                if error != nil {
                    print("\(error!.localizedDescription)")
                    return
                }

                // Get data
                jsonData = try! JSON(data: data!)
                // print(jsonData)
            }
            task.resume()
        }//  ./ dispatch aync
        completion(jsonData)
    }

此函数托管在一个单独的 Swift 文件中,现在在我的 ViewController.swift 中,我按如下方式调用该函数:

getJSONdata(fileName: "Users") { (jsonData) in
    print("\(jsonData)")
}

在这种情况下,我在我的 Xcode 控制台中得到一个空数组,相反,如果我取消注释我的 getJSONdata() 函数中的 // print(jsonData),控制台会打印出我的 JSON 数据。

显然我在 getJSONdata() 函数中做错了,因为我无法通过调用 ViewController.swift 来检索数据。

我的函数中的错误在哪里?

【问题讨论】:

  • 如果将completion(jsonData) 移动到jsonData = try! JSON(data: data!) 下会发生什么
  • 您应该在从 API 获得响应/数据后调用完成处理程序。
  • 好的,但这是我得到的:i.postimg.cc/g0gz2wvy/error.png
  • 谢谢@chirag90,你说得对,我还必须将 @escaping 添加到我的函数声明中。

标签: php ios json swift


【解决方案1】:

试试下面的代码。也许它会帮助你。

func getJSONdata(fileName:String, completion:@escaping (_ json:JSON)->()) {
            let session = URLSession(configuration: .ephemeral)
            var jsonData = JSON()

            let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
            var request = URLRequest(url:myUrl!)
            request.httpMethod = "POST"
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            DispatchQueue.main.async {
                let task = session.dataTask(with: request) { (data, response, error)  in
                    if error != nil {
                        print("\(error!.localizedDescription)")
                        completion(nil)
                    }

                    // Get data
                    jsonData = try! JSON(data: data!)
                    // print(jsonData)
                    completion(jsonData)
                }
                task.resume()
            }
        }

【讨论】:

  • 谢谢,但由于某种原因,它不起作用,如下所示:i.postimg.cc/g0gz2wvy/error.png。无论如何,我已经发布了一个答案,这是我的问题的解决方案,希望它可以帮助其他人。
  • 无论如何,我已经更新了我的答案。请检查您是否有任何疑问。
【解决方案2】:

我找到了一个解决方案,我不知道为什么,但是如果我将@escaping 添加到我的函数声明中,它就可以正常工作。

按照@chirag90 的建议,我还必须将completion(jsonData) 移动到jsonData = try! JSON(data: data!) 下方。

那么,完整的功能如下:

func getJSONdata(fileName:String, completion: @escaping (_ json:JSON?) -> Void) {
        let session = URLSession(configuration: .ephemeral)
        var jsonData = JSON()

        let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
        var request = URLRequest(url:myUrl!)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        DispatchQueue.main.async {
            let task = session.dataTask(with: request) { (data, response, error)  in
                if error != nil {
                    self.simpleAlert("\(error!.localizedDescription)")
                    return
                }

                // Get data
                jsonData = try! JSON(data: data!)
                completion(jsonData)
            }
            task.resume()
        }//  ./ dispatch aync
    }

【讨论】:

  • 谢谢,我会的,但我只能在 2 天内做到这一点,而不是现在 :)
  • 不要使用 SwiftyJSON。看看 Codable 协议
  • 为什么我不应该使用 SwiftyJSON?它让我节省了大量的代码行
猜你喜欢
  • 2017-11-17
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 2021-12-05
  • 1970-01-01
  • 2013-12-06
相关资源
最近更新 更多