【问题标题】:Can't access decoded JSON data (from API) outside the URLSession data task Function Scope无法访问 URLSession 数据任务功能范围之外的解码 JSON 数据(来自 API)
【发布时间】:2021-12-15 10:37:14
【问题描述】:

我在尝试从 API 检索和解码 JSON 数据时遇到问题。我能够从 API 获取数据并成功解码,但我无法从函数范围之外访问它。我正在使用以下函数来获取和解码数据。 API 返回一个 JSON 对象数组。

func getJSON(completed: @escaping () -> ()) {
        
        var jsonData = [API_data] () // A struct for retrieved data
        
        let url = "URL Here" // I have the original URL here, which I can't share

        let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { [self]data,response,error in
            
            guard let data = data, error == nil else{
                print("error")
                return
            }
            
            do{
            
                jsonData = try JSONDecoder().decode([API_data].self,from:data)
                
            } catch{
                print(error)
            }
        
            
            print(jsonData[0].id) // This prints my data
            
        })
        
        print(jsonData[0].id) // This won't print my data

        
        task.resume()
        
    }
struct API_data: Codable {
    let id : String
}

因此,我无法在应用程序的任何地方使用这些数据。任何帮助将不胜感激。我也试过将jsonData设为全局变量,在函数中更新它并返回它然后使用它,仍然不起作用。

感谢您的帮助。

【问题讨论】:

    标签: json swift api


    【解决方案1】:

    因为您已经有一个完成处理程序,所以使用它并传递接收到的数据

    func getJSON(completed: @escaping ([API_data]) -> Void) {
        
        let url = "URL Here" // I have the original URL here, which I can't shar
        let task = URLSession.shared.dataTask(with: URL(string: url)!) { data, _ , error in
            
            if let error = error { print(error); return }
            
            do {
                completed(try JSONDecoder().decode([API_data].self,from:data!))
            } catch{
                print(error)
            }
        }
        task.resume()
    }
    

    并使用它

    getJSON { apiData in 
        print(apiData[0].id) // This prints my data
    }
    

    或者更喜欢Result 类型

    func getJSON(completed: @escaping (Result<[API_data],Error>) -> Void) {
        
        let url = "URL Here" // I have the original URL here, which I can't shar
        let task = URLSession.shared.dataTask(with: URL(string: url)!) { data, _ , error in
            
            if let error = error { completed(.failure(error)); return }
            Result { try JSONDecoder().decode([API_data].self,from: data!) }
        }
        task.resume()
    }
    
    
    getJSON { result in 
        switch result {
            case .success(let apiData): print(apiData[0].id) // This prints my data
            case .failure(let error): print(error)
        }
        
    }
    

    【讨论】:

      【解决方案2】:

      它是异步的,您可能希望稍后在它准备好时访问它,例如通过使用完成处理程序。

      【讨论】:

        【解决方案3】:

        尝试从您的 API 函数创建一个完成处理程序并发送完成后的数据。并尝试在那里使用它。

        【讨论】:

        • 提供一个确定的答案总是比要求 OP 尝试一些东西更好。
        猜你喜欢
        • 1970-01-01
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-11
        相关资源
        最近更新 更多