如何使用方法调用 API

How to hit an API call using a method

我目前正在使用 SwiftUI 开发应用程序。

我想在点击按钮时点击 API。

但是我的代码不起作用。 (*当我使用控制台点击 API URL 时,我可以检查我收到了一个值。)

在 ShowAPI 结构中点击按钮时如何使用 load() 方法?


代码如下:

ContentView.swift

import SwiftUI

struct ContentView: View {
    @ObservedObject var hitAPI = HitAPI()

    var body: some View {

    ShowAPI()
        .environmentObject(hitAPI)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

ShowAPI.swift

import SwiftUI

struct ShowAPI: View {
    
    @EnvironmentObject var hitAPI: HitAPI
    
    var body: some View {
        Text(hitAPI.infos?.name ?? "")
   
        Button(action: {
            HitAPI().load()
        }, label: {
            Text("GET")
        })
    }
}

struct ShowAPI_Previews: PreviewProvider {
    static var previews: some View {
        ShowAPI()
    }
}

HitAPI.swift

import Foundation
import Combine

class HitAPI: ObservableObject {
    
    @Published var infos: Infos?
    
//        init() {
//            load()
//        }
    
    func load() {

        guard let urlStr = "https://sample.com/api/test/1/"
                .addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
        else {
            fatalError("URL String Error")
        }
        
        guard let url = URL(string: urlStr) else {
            fatalError("URL convert Error")
        }
        
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            if data != nil{
                DispatchQueue.main.async {
                    self.infos = try! JSONDecoder().decode(Infos.self, from: data!)
                    print(self.infos!.name)//I can check a value in a console
                }
            }else{
                fatalError("JSON Data decode Error")
            }
        }
        task.resume()
        
    }
}

struct Infos: Codable {
    var name: String
}

如果我在init()中使用load()方法,Text(hitAPI.infos?.name ?? "")显示一个值


Xcode:版本 12.0.1

您每次调用加载时都在创建一个新的 HitAPI,这没有给它足够的时间在被释放之前完成请求:

import SwiftUI

struct ShowAPI: View {
    
    @EnvironmentObject var hitAPI: HitAPI
    
    var body: some View {
        Text(hitAPI.infos?.name ?? "")
   
        Button(action: {
            HitAPI().load()
        }, label: {
            Text("GET")
        })
    }
}

struct ShowAPI_Previews: PreviewProvider {
    static var previews: some View {
        ShowAPI()
    }
}

改成这样:


struct ShowAPI: View {
    
    @EnvironmentObject var hitAPI: HitAPI
    
    var body: some View {
        Text(hitAPI.infos?.name ?? "")
   
        Button(action: {
            hitAPI.load()
        }, label: {
            Text("GET")
        })
    }
}

struct ShowAPI_Previews: PreviewProvider {
    static var previews: some View {
        ShowAPI()
    }
}