使用 API 时我在这里做错了啥?

Posted

技术标签:

【中文标题】使用 API 时我在这里做错了啥?【英文标题】:What did I do wrong here when working with an API?使用 API 时我在这里做错了什么? 【发布时间】:2020-06-06 19:44:52 【问题描述】:

首先:我是 Swift 和 SwiftUI 的初学者。我将不胜感激任何帮助,即使它与我的问题无关! 现在我的问题: 为了练习 SwiftUI 和 API,我想构建一个小应用程序来显示有关冠状病毒的一些数据,非常简单。这是我使用的 API:Coronavirus API。 现在这是我的代码:

import SwiftUI

struct GlobalResult: Decodable 
    var cases: Int
    var deaths: Int
    var recovered: Int


struct Statistics : View 
    @State var global: GlobalResult!

    var body: some View 
         VStack 
              VStack 
                Text("\(self.global.cases)")
              
         .onAppear() 
               ApiShared.shared.getData()
         
     




class Api 
    @Published var data: GlobalResult!

func getData() 
    let url = "https://corona.lmao.ninja/v2/all"

    let session = URLSession(configuration: .default)

    session.dataTask(with: URL(string: url)!)  (data, _, err) in

        if err != nil 

            print((err?.localizedDescription)!)
            return
        

        let json = try! JSONDecoder().decode(GlobalResult.self, from: data!)

        DispatchQueue.main.async 
            self.data = json
        
    
    .resume()



class ApiShared 
    static let shared = Api()


struct Statistics_Previews: PreviewProvider 
    static var previews: some View 
        Statistics()
    

但它不起作用!我遵循了一些关于 YT 的教程,并且可以使其正常工作。有人可以帮我吗? 当我删除 if 语句 它说“致命错误:在隐式展开可选值时意外发现 nil” 非常感谢!

【问题讨论】:

if 语句中显示的localizedDescription 是什么? tbh,我真的不知道,它来自教程。但我认为那是错误 几件事:避免使用! 来强制包装可选值。而不是 print((err?.localizedDescription)!) 做 print((err?.localizedDescription) ?? "")。这应该可以帮助您进一步调试以及发生了什么。 data! 相同。我没有意识到你在两个不同的地方大获全胜。无论发生 fata 错误,您都希望它优雅地失败,以便您可以继续调试您的问题 我应该如何处理“!”? 【参考方案1】:

我从未使用过 SwiftUI,但在我看来问题出在其中。与您的 var 数据有关的内容。 我稍微改变了你的功能。

func getData() 
    let url = "https://corona.lmao.ninja/v2/all"
    let session = URLSession(configuration: .default)
    session.dataTask(with: URL(string: url)!)  (data, responce, err) in
        if let error = err 

            print(error.localizedDescription)
            return
        
        if let responce = responce
            print(responce)
        

        if let data = data
            do 
                let json = try JSONDecoder().decode(GlobalResult.self, from: data)
                print(json)
             catch
                print(error.localizedDescription)
            
        
    
    .resume()

得到了结果。尝试以相同的方式更改函数,您将在控制台中看到打印的响应,这意味着 var 数据确实存在问题。

【讨论】:

是的,你说得对!我在控制台中看到它。现在我必须弄清楚如何显示它。 您找到解决问题的方法了吗?【参考方案2】:

上一个答案提供了一种安全获取数据而不会崩溃的好方法,但是您仍然没有将 getData() 函数的结果设置为视图中的全局变量。尝试更改您的 getData() 函数以返回如下所示的 GlobalResult 对象:

func getData() -> GlobalResult? 
     let url = "https://corona.lmao.ninja/v2/all"
     let session = URLSession(configuration: .default)
     session.dataTask(with: URL(string: url)!)  (data, responce, err) in
         if let error = err 
             print(error.localizedDescription)
             return nil
         
         if let responce = responce
             print(responce)
         

         if let data = data
             do 
                 let json = try JSONDecoder().decode(GlobalResult.self, from: data)
                 print(json)
                 return json
              catch
                 print(error.localizedDescription)
                return nil
             
         
     
     .resume()
 

如果成功则返回 GlobalResult 值,否则返回 nil。然后在您的统计视图中,您可以执行以下操作:

struct Statistics : View 
@State var global: GlobalResult!

var body: some View 
     VStack 
          VStack 
            Text("\(self.global.cases)")
          
     .onAppear() 
           let result = ApiShared.shared.getData()
           if result != nil 
               global = result
           
     
     
 

这将获取 getData() 调用的结果,如果不为零,则将其设置为全局变量。我认为您不需要 Api 类中的 @Published 变量。

【讨论】:

感谢您的回答,但是当我输入“return nil”或“return json”时,它会显示“在 void 函数中出现意外的非 void 返回值” 确保您的 getData() 函数定义被编写为返回 GlobalResult?类型。请参阅我的第一个代码 sn-p 的顶部。

以上是关于使用 API 时我在这里做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章

创建这个动态生成的表时我做错了啥?

Batch-API:我在这段代码中做错了啥?

没有为该类定义 Getter。我在这里做错了啥?

我在 Laravel 8 Cors 中做错了啥配置?

嗨,我正在尝试学习 Apache 骆驼框架。我不知道我在这里做错了啥

R语言中的一类分类。生成混淆矩阵时我做错了啥?