SwiftUI:使用 Text() 而不是 List 显示 JSON 数据



我在 SwiftUI 视图上显示 JSON 数据时遇到问题。 我尝试了几个教程并阅读了与我的问题相关的文章,但似乎没有什么足够合适。

例如,每个人都使用精美的列表或图片显示来自API的JSON数据,但我只想知道如何在视图上简单地显示一个单词(没有List{}(。

我选择了PokeAPI来弄清楚如何使用Text()指令显示">Hi Charmander"。

列表示例(不带ObservableObject@Published(

我想摆脱列表并使用 sth。Text(resultsVar[0].name).onAppear(perform: loadData)喜欢

import SwiftUI
struct pokeRequest:Codable {
var results: [Result]
}
struct Result:Codable {
var name:String
}
struct ViewOne: View {
@State var resultsVar = [Result]()
var body: some View {
VStack{
//unfortunately this does not work:
//Text(resultsVar[0].name).onAppear(perform: loadData)
List(resultsVar, id: .name) { item in
VStack(alignment: .leading) {
Text("Hi (item.name)")
}
}
.onAppear(perform: loadData)
}
}
func loadData(){
guard let url = URL(string: "https://pokeapi.co/api/v2/pokemon?offset=3&limit=3") else {
print("Invalid URL")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let decodedResponse = try? JSONDecoder().decode(pokeRequest.self, from: data) {
DispatchQueue.main.async {
self.resultsVar = decodedResponse.results
}
return
}
}
print("Fetch failed: (error?.localizedDescription ?? "Unknown error")")
}.resume()
}
}
struct ViewOne_Previews: PreviewProvider {
static var previews: some View {
ViewOne()
}
}

第二次尝试使用不同的方法(没有.onAppear()(在这种方法中,我尝试了class: Observable Object@Published但我也没有达到我想要的 UI 输出。

import SwiftUI
struct pokeRequest2:Codable {
var results2: [pokeEach2]
}
struct pokeEach2:Codable {
var name2:String
}

class Webservice:ObservableObject {
@Published var pokeInfo: [pokeRequest2] = [pokeRequest2]()
func decodepokemon() {
let session = URLSession.shared
let url = URL(string: "https://pokeapi.co/api/v2/pokemon?offset=3&limit=3")!
let task = session.dataTask(with: url) { data, response, error in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
print("Server error!")
return
}
guard let mime = response.mimeType, mime == "application/json" else {
print("Wrong MIME type!")
return
}
do {
let response = try JSONDecoder().decode(pokeRequest2.self, from: data!)
print(self.pokeInfo[0].results2[0].name2)
DispatchQueue.main.async {
self.pokeInfo = [response]
}
}  catch {
print("JSON error: (error.localizedDescription)")
}
}.resume()
}
init() {
decodepokemon()
}
}
struct ViewTwo: View {
@ObservedObject var webservice: Webservice = Webservice()
var body: some View {
Text("please help")
//Does also not work: Text(self.webservice.pokeInfo2[0].results2[0].name2)//.onAppear()
//Since a few minutes somehow the debug area prints "JSON error: The data couldn’t be read because it is missing." instead of "charmander"
}
}
struct ViewTwo_Previews: PreviewProvider {
static var previews: some View {
ViewTwo()
}
}

我尝试了几个教程并阅读了与我的问题相关的文章,但似乎没有什么足够合适。我将非常感谢任何帮助:-( 提前感谢!

我绝不是专家(不到三天前开始使用 Swift(,但我想我可能拥有您想要的东西。这使您能够调用仅包含简单字典的简单 REST API(在我的例子中,字典包含"差异":5.22(,然后在按下按钮时将该数字显示为文本。希望以下内容对您有所帮助!

struct DifferentialData: Decodable {
var Differential: Double
}
struct ContentView: View {
@State var data = DifferentialData(Differential: 0.00)
func getData() {
guard let url = URL(string: "Enter your URL here")
else { return } //Invalid URL

URLSession.shared.dataTask(with: url) { data, response, error in
let differentials = try!       JSONDecoder().decode(DifferentialData.self, from: data!)
print(differentials)
DispatchQueue.main.async {
self.data = differentials
}
}
.resume()
}
var body: some View {

VStack{
Text("(data.Differential)")
Button("Refresh data") {self.getData()}
}
}
}

我可能误解了这个问题,但在 SwiftUI 中文本可以显示如下:

Text("Hi" + item.name)

但正如我所说,我不确定这是否是问题所在。

由于您将动态更改列表项,因此必须使用 .id(( 修饰符。并且为了使用 .id((,结果必须符合Hashable。以下代码可以帮助您解决问题。

struct Result:Codable, Hashable {
var name:String
}
struct ViewOne: View {
@State var resultsVar = [Result]() // [Result(name: "firsy"),Result(name: "second"), ]//[Result]()
var body: some View {
VStack{
Spacer()
//unfortunately this does not work:
//Text(resultsVar[0].name).onAppear(perform: loadData)
List(resultsVar, id: .name) { item in
VStack(alignment: .leading) {
Text("Hi (item.name)")
}
}.id(resultsVar)
}.onAppear(perform: loadData)

相关内容

最新更新