【问题标题】:Display decoded JSON Dictionary values in SwiftUI Text() without using a List在 SwiftUI Text() 中显示解码的 JSON 字典值而不使用列表
【发布时间】:2020-10-14 22:14:00
【问题描述】:

我以前从未使用过 SwiftUI,但我已经设法为我们的帮助台获得了一个功能正常的应用程序,所以请耐心等待。在主要内容视图中,我已成功从带有 JSON 的链接中获取所有票证,并将有限的数据显示在所有票证的列表中。当您单击工单时,它会打开第二个视图,其中仅包含从主视图传递的工单的有限信息和一些操作按钮。在第二个视图中,我创建了一个调用来获取该特定票证的所有详细信息(JSON 字典),但我终其一生都无法弄清楚如何显示该数据,即使我可以在控制台中打印它。

import SwiftUI

struct TicketDetails: Codable, Identifiable {
    var id: Int
    var type: String
    var location: Location
}

struct Location: Codable {
    let locationName: String
}

class FetchTick {
    func getTicket(completion: @escaping (TicketDetails) -> ()) {
        guard let url = URL(string: "URLWITHSENSITIVEINFOREMOVEDFORDEMO") else { return }
        URLSession.shared.dataTask(with: url) {(data, _, _) in
            let ticket = try! JSONDecoder().decode(TicketDetails.self, from: data!)
            DispatchQueue.main.async {
                completion(ticket)
            }
            print(ticket)
        }
        .resume()
    }
}

struct DetailsView: View {
    @ObservedObject var ticketStatusAction = TicketStatusAction()
    @State var ticket: [TicketDetails] = []
    @State private var showingOpenAlert = false
    @State private var showingDepotAlert = false
    @State private var showingCloseAlert = false

    // These are passed in from the Primary View and display fine below
    var id: Int
    var type: String
    var displayClient: String
    var shortDetail: String
    
    var body: some View {
        VStack (alignment: .leading){
            Text("\(id)")
                .onAppear {
                    FetchTick().getTicket { (ticketDetails) in
                        self.ticket = self.ticket
                    }}
                .padding()
            
            Text("\(displayClient)")
                .fontWeight(.bold)
                .font(.system(size:20))
                .padding()

            Divider()
            Text("\(shortDetail)")
                .padding()
            HStack() {
                
                Button(action: {
                    self.showingOpenAlert = true
                }) {
                    Text("Set to Open")
                    .fontWeight(.bold)
                    .font(.system(size:11))
                    .padding()
                    .background(Color.green)
                    .cornerRadius(40)
                    .foregroundColor(.white)
                    .padding(5)
                }.buttonStyle(BorderlessButtonStyle()).alert(isPresented:self.$showingOpenAlert) {
                    Alert(
                        title: Text("Are you sure you want change \(displayClient)'s ticket to Open?"),
                        primaryButton: .destructive(Text("Set Open"))
                            {
                            self.ticketStatusAction.TicketAction(ticketId: self.id, desiredStatus: 1)
                            },
                        secondaryButton: .cancel())
                }
                
                Button(action: {
                    self.showingDepotAlert = true
                }) {
                    Text("Depot Ticket")
                    .fontWeight(.bold)
                    .font(.system(size:11))
                    .padding()
                    .background(Color.blue)
                    .cornerRadius(40)
                    .foregroundColor(.white)
                    .padding(5)
                }.buttonStyle(BorderlessButtonStyle()).alert(isPresented:self.$showingDepotAlert) {
                    Alert(
                        title: Text("Are you sure you want to depot \(displayClient)'s ticket?"),
                        primaryButton: .destructive(Text("Depot"))
                            {
                            self.ticketStatusAction.TicketAction(ticketId: self.id, desiredStatus: 6)
                            },
                        secondaryButton: .cancel())
                }
                
                Button(action: {
                    self.showingCloseAlert = true
                }) {
                    Text("Close Ticket")
                    .fontWeight(.bold)
                    .font(.system(size:11))
                    .padding()
                    .background(Color.red)
                    .cornerRadius(40)
                    .foregroundColor(.white)
                    .padding(5)
                }.buttonStyle(BorderlessButtonStyle()).alert(isPresented:self.$showingCloseAlert) {
                    Alert(
                        title: Text("Are you sure you want to close \(displayClient)'s ticket?"),
                        primaryButton: .destructive(Text("Close"))
                            {
                            self.ticketStatusAction.TicketAction(ticketId: self.id, desiredStatus: 3)
                            },
                        secondaryButton: .cancel())
                }
            }
        }
    }
}

当我运行这个并访问这个视图时(见截图),它成功打印了

TicketDetails(id: 2282, type: "Ticket", location: WHD.Location(locationName: "DES"))

所以我知道我实际上得到了正确的数据。

如何将这些数据(例如票的位置名称)放入 Text() 字段?

【问题讨论】:

  • self.ticket = self.ticket?
  • 这有什么帮助?如果我在代码中更改它,我会收到错误“无法分配类型 '[TicketDetails] 的值?”输入 '[TicketDetails]'" 此外,这只会影响控制台中显示的代码。
  • 我在问为什么你的代码中有self.ticket = self.ticket?这似乎是问题
  • 啊,我明白了。好吧,我想我到了那里是因为 XCode 抛出错误,这是它给我的建议,它在控制台中生成了我需要的数据。

标签: json swift swiftui


【解决方案1】:

正如我从代码中看到的那样(未测试,由于提供了不可测试的快照)

Text("\(id)")
    .onAppear {
        FetchTick().getTicket { (ticketDetails) in
            self.ticket = [ticketDetails]   // ticket declared as [TicketDetails]
        }}
    .padding()
         
if !ticket.isEmpty {
   Text(self.ticket.first?.location.locationName ?? "") 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    相关资源
    最近更新 更多