如何使用方法调用 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()
}
}
我目前正在使用 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()
}
}