使用 Codable 解码 JSON,然后填充我的 SwiftUI

Posted

技术标签:

【中文标题】使用 Codable 解码 JSON,然后填充我的 SwiftUI【英文标题】:Decode JSON using Codable and then populate my SwiftUI 【发布时间】:2020-08-25 01:13:31 【问题描述】:

我是 Swift 和 SwiftUI 的新手。我目前正在通过 hackingwithswift.com 教自己如何编码(喜欢它!)我目前正处于第 60 天,我被困住了,不知道从这里开始做什么。

挑战是使用 Codable 解码一些信息并填充 SwiftUI。

我创建了一个结构来匹配 JSON,但是当我运行应用程序时,我不断收到错误“Fetch Failed: Unknown Error”,因此我的 UI 不会更新。

有人会看一下我的代码并提供任何关于我出错的地方以及可能的原因的指示吗?非常感谢您的任何建议和帮助,非常感谢!代码贴在下面。

科迪

import SwiftUI

struct Response: Codable 
    var results: [User]


struct User: Codable, Identifiable 
    let id: String
    let isActive: Bool
    let name: String
    let age: Int
    let company: String
    let email: String
    let address: String
    let about: String
    let registered: String
    let tags: [String]
    
    struct FriendRole: Codable 
        let id: String
        let name: String
    
    
    let friend: [FriendRole]
    


struct ContentView: View 
    @State private var results = [User]()
    
    var body: some View 
        List(results, id: \.id)  item in
            VStack(alignment: .leading) 
                Text(item.name)
                    .font(.headline)
                Text(item.address)
            
        
    .onAppear(perform: loadData)
    
    
    func loadData() 
        guard let url = URL(string: "https://www.hackingwithswift.com/samples/friendface.json") 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(Response.self, from: data) 
                    DispatchQueue.main.async 
                        self.results = decodedResponse.results
                    
                    return
                
            
            print("Fetch Failed: \(error?.localizedDescription ?? "Unkown Error").")
        .resume()
    


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

【问题讨论】:

let friend 应该是 let friends。不要使用try?。使用 do/catch 语句。 【参考方案1】:

我也是 swiftUI 的新手,这就是我设法通过使用可观察对象使其工作的方式

这是结构因为在 json 文件中有一个 [ 一开始您不必创建具有用户数组的结构,您可以创建一个结构,然后将该结构类型的变量创建为数组

我是这样做的

我为结构创建了单独的文件,例如我为它们创建了不同的文件

这是我的结构文件

import Foundation



struct User : Codable, Identifiable 
    let id : String
    let isActive : Bool
    let name : String
    let age : Int
    let company : String
    let email : String
    let address : String
    let about : String
    let registered : String
    let tags = [String]()
    let friends = [Friends]()



struct Friends : Codable 
    let id : String
    let name : String


我为可观察对象类创建了另一个文件

class JsonChannel : ObservableObject 
    @Published var retVal = [User]()
    func getInfo () 
        guard let url = URL(string: "https://www.hackingwithswift.com/samples/friendface.json") else return
        URLSession.shared.dataTask(with: url)  (data, resp, err) in
            if let data = data 
                DispatchQueue.main.async 
                    do 
                        self.retVal = try JSONDecoder().decode([User].self, from: data)
                    
                    catch 
                        print(error)
                    
                
            
        .resume()
    

这就是我的 contentView 文件的内容

import SwiftUI

struct ContentView : View 
    @ObservedObject var info = JsonChannel()
    var body: some View 
        VStack 
            Button(action: 
                self.info.getInfo()
            ) 
                Text("click here to get info")
            
            List 
                ForEach (self.info.retVal)  item in
                    VStack 
                        Text("\(item.name)")
                        Text("\(item.address)")
                    
                    
                
            
        
    


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


【讨论】:

非常感谢您的帮助,非常感谢!这有效:)

以上是关于使用 Codable 解码 JSON,然后填充我的 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

如何使用解码器将给定 JSON 中 Double 类型的 Codable 属性转换为 Date?

如何使用 Codable 解码具有更改键的 json 响应?

Swift Codable 将空 json 解码为 nil 或空对象

使用 swift Codable 以值作为键来解码 JSON

使用 Codable 将接收到的 Int 转换为 Bool 解码 JSON

如何使用 Codable 从字典中解码 .key