Json 未在 SwiftUI 中加载

Posted

技术标签:

【中文标题】Json 未在 SwiftUI 中加载【英文标题】:Json not loading in SwiftUI 【发布时间】:2021-10-03 05:59:58 【问题描述】:

我正在尝试将此 json 加载到我的 swiftui 应用程序中

 
            "id": "EF1CC5BB-4785-4M8E-AB98-5FA4E00B6A66",
            "name" : "opening the box",
            "group" : [
            
            
                "name" : "Open  box",
                "windows" : "Double-click",
                "mac" : "right-click"
                
            ,
            
                "name" : "Duplicate",
                "windows" : "right click and choose from options",
                "mac" : "option + drag"
                
            
            
            
            
            
            ]
        ,

还有更多这样的元素

这是我制作的结构

struct topic: Codable, Identifiable 
    
    var id: UUID
    var name: String
    var group: [shortcuts]
    
    


struct shortcuts: Codable, Equatable, Identifiable
    
    var id = UUID()
    var name: String
    var windows: String
    var mac: String


这是解码它的代码

import UIKit

extension Bundle 
    
    func decode<T: Decodable>(_ type: T.Type, from file: String) -> T 
        
        guard let url = self.url(forResource: file, withExtension: nil) else 
            
            fatalError("failed")
      
        
        
        guard let data = try? Data(contentsOf: url) else 
            
            
            fatalError("failed to do it")
            
        
        
        let decoder = JSONDecoder()
        
        guard let loaded = try? decoder.decode(T.self, from: data) else 
            fatalError("failed")
        
        return loaded
        
    
    
    
    
    

现在当我在视图中创建这样的常量时

 let Topic = Bundle.main.decode([topic].self, from: "main.json")

然后我尝试加载这样的项目

 NavigationView
                List
                    ForEach(Topic)  section in
                        Section(header: Text(section.name)) 
                            ForEach(section.group)  item in
                                shortcutRow(item: item)
                            
                        
                        
                        
     
                
                
            .navigationBarTitle("Menu")
             .listStyle(SidebarListStyle())
                
            
        

它不起作用,它显示了我为解码此 json 而创建的捆绑扩展的倒数第二行代码中存在的致命错误

请帮忙

【问题讨论】:

你的结构不正确。请检查:***.com/a/61483237/5941807 " 它显示了我的代码的倒数第二行中出现的致命错误“不要这样做fatalError,而是正确的do/try/catch并打印捕获的error 而不是try?,因为您当前忽略了可以准确告诉您失败原因的错误! 查看我之前关于为什么使用 do/try/catch 的答案:***.com/questions/69002011/… 【参考方案1】:

“...还有更多这样的元素”,这意味着您显示的json 可能不是您拥有的json。很可能它是您展示的一系列内容。 因此,在Bundle decode 中,您应该解码并返回[T] 而不是T。 请注意,您应该使用对类型使用大写名称的常规约定, 例如Topic,以及实例的小写名称topic。鉴于此,试试这个:

extension Bundle 
    
    // todo deal with errors
    func decode<T: Decodable>(from file: String) -> [T]   // <-- here
        if let url = Bundle.main.url(forResource: file, withExtension: "json") 
            do 
                let data = try Data(contentsOf: url)
                let loaded = try JSONDecoder().decode([T].self, from: data)  // <-- here
                return loaded
             catch 
                // todo deal with errors
                print("---> error: \(error)")
            
         else 
            // todo deal with errors
            print("---> error url: ")
        
        return []
    
    


struct Topic: Codable, Identifiable 
    var id, name: String
    var group: [Shortcuts]


struct Shortcuts: Codable, Identifiable 
    let id = UUID()  // <-- here use let
    var name, windows, mac: String


struct ContentView: View 
    let topics: [Topic] = Bundle.main.decode(from: "main") // <-- here
    
    var body: some View 
       Text("testing topics: \(topics.count)")
        .onAppear 
            print("---> topics: \(topics)")
        
    

编辑:

这是我用来测试答案的 json 数据:

[

           "id": "EF1CC5BB-4785-4M8E-AB98-5FA4E00B6A66",
           "name" : "opening the box",
           "group" : [
           
               "name" : "Open  box",
               "windows" : "Double-click",
               "mac" : "right-click"
           ,
           
               "name" : "Duplicate",
               "windows" : "right click and choose from options",
               "mac" : "option + drag"
           
           ]
       
]

【讨论】:

请考虑泛型类型T 既可以是单个对象也可以是数组,具体取决于传递的参数类型。 是的,当然,但我认为显示它是一个数组更容易。 但是JSON的根对象显然是一个字典。出现该错误是因为shortcuts 中没有id 键,并且没有指定CodingKeys 来排除id 错误,在Shortcuts 中使用let id = UUID() 将确保id 不被解码。甚至 Xcode 也会告诉你这么多。我已经测试了我的答案并将 json 数据设置为数组 [...],因为它可能应该放在首位。 点了,这是个玩笑,不要当真,向大家道歉。

以上是关于Json 未在 SwiftUI 中加载的主要内容,如果未能解决你的问题,请参考以下文章

ExtJS 组合框未在面板中加载

ng build 后,字体真棒字体未在 Angular 中加载

如何在 Swift 中加载远程 JSON 文件?

UIWebView 未在 ios 中加载

url 未在 UIWebView 中加载

数据未在 UITableView 中加载。可能是啥问题?