调用函数使用URLSession检索JSON后,数组返回空值

wztqucjr  于 2022-12-30  发布在  其他
关注(0)|答案(1)|浏览(121)

我正在使用URLSession从URL检索JSON格式的数据。在解码JSON数据后,出于调试原因,我将其打印出来,并填充一个struct CVE数组。该数组在函数jsonDataRequest中有数据,但当我尝试从ViewController获取其元素时,该数组为空。我花了很长时间搜索如何解决它,但我有点卡住了。以下是我的代码:
在类中,我有以下代码:该结构

struct CVE : Decodable
    {
        var CVE : String
        var severity : String
        var cvss3_score : String? = nil
        var public_date : String
        var bugzilla_description : String
        
    }
    struct CVEdata : Decodable
    {
        var cves : [CVE]
    }

要从ViewController使用的数组

var arrCVE : [CVE] = []

从ViewController调用的函数

func jsonDataRequest ()
    {
        let url = "https://access.redhat.com/hydra/rest/securitydata//cve.json?after=2022-12-26"
        let urlObj = URL(string: url)
        URLSession.shared.dataTask(with: urlObj!) { (data, response, error) in
            do
            {
                // Json to Array
                self.jsonCVE = try JSONDecoder().decode([CVE].self, from: data!)
                
                var strCVE : String
                var strSeverity : String
                var strCvss3_score : String? = nil
                var strPublic_date : String
                var strBugzilla_description : String
                
                print(self.jsonCVE)
                for oCVE in self.jsonCVE
                {
                    print(oCVE.CVE + " " + oCVE.severity + " " + oCVE.public_date + " " + oCVE.bugzilla_description)
                    
                    // get each the CVE info
                    strCVE = oCVE.CVE
                    strSeverity = oCVE.severity
                    if (oCVE.cvss3_score != nil)
                    {
                        print(oCVE.cvss3_score!)
                        strCvss3_score = oCVE.cvss3_score
                    }
                    else
                    {
                        print("")
                        strCvss3_score = ""
                    }
                    strPublic_date = oCVE.public_date
                    strBugzilla_description = oCVE.bugzilla_description
                    
                    // save it to the array
                    self.arrCVE.append(CVE(CVE: strCVE, severity: strSeverity, cvss3_score: strCvss3_score, public_date: strPublic_date, bugzilla_description: strBugzilla_description))
                    print(self.arrCVE)
                }
               
                // Logic after response has arrived
                DispatchQueue.main.async
                {
                    print("main.async")
                }
            } catch
            {
                print(error)
            }
        }.resume()
    }

在ViewController中,我示例化了类中的一个对象并访问数组。我在UITextView上显示了数组。count,以查看它包含多少行

let oRedHatCVEs = RedHatCVEs()
oRedHatCVEs.jsonDataRequest()
txtvJSON.text = "Array elements: " + String(oRedHatCVEs.arrCVE.count)

结果是数组元素:0
这和上面代码的异步工作方式有关吗?我怎样才能最终将数组数据返回到我的ViewController?

ru9i0ody

ru9i0ody1#

你是对的,这与异步函数jsonDataRequest有关。在使用数据之前,有很多方法可以处理(即等待)异步函数完成。
这个示例代码展示了一种使用Swift async/await框架的方法,它还缩短了获取数据的代码。

class RedHatCVEs {
     var arrCVE: [CVE] = []

     func jsonDataRequest() async {
         if let url = URL(string: "https://access.redhat.com/hydra/rest/securitydata/cve.json?after=2022-12-26") {
             do {
                 let (data, _) = try await URLSession.shared.data(from: url)
                 arrCVE = try JSONDecoder().decode([CVE].self, from: data)
             }
             catch {
                 print(error)
             }
         }
     }
 }

像这样使用它:

let oRedHatCVEs = RedHatCVEs()
 Task {
     await oRedHatCVEs.jsonDataRequest()
     txtvJSON.text = "Array elements: " + String(oRedHatCVEs.arrCVE.count)
 }

相关问题