在SwiftUI Text()中显示解码的JSON字典值,而无需使用列表

时间:2020-06-24 15:31:03

标签: json swift swiftui

我以前从未使用过SwiftUI,但是我设法为我们的帮助台获得了功能正常的应用程序,因此请多多包涵。在主Content View上,我已经成功地从JSON链接中获取了所有票证,并在所有票证列表中显示了有限的数据。当您单击故障单时,它会打开第二个视图,仅从主视图和某些操作按钮传递该故障单的有限信息。在第二个视图中,我创建了一个调用,该调用获取该特定凭单的所有详细信息(JSON字典),但是即使可以在控制台中打印数据,我也无法确定如何显示该数据。< / p>

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"))

所以我知道我实际上正在获取正确的数据。

enter image description here

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

1 个答案:

答案 0 :(得分:0)

正如我从代码中看到的那样,它是如何实现的(由于未提供可测试的快照,因此未经测试)

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