【问题标题】:Need help targeting a nested json object SwiftUI *Question clarified*需要针对嵌套 json 对象 SwiftUI 的帮助 *已澄清问题*
【发布时间】:2021-05-22 20:57:25
【问题描述】:

当我试图在嵌套的 json 对象中显示来自数组的信息时,我目前正在碰壁。我不明白我哪里出错了,所以任何帮助都将不胜感激。 **我收到的当前错误是:致命错误:索引超出范围

我相信我的问题可能与我如何定位信息有关。我已经使用“!! ... !!”进行了概述我认为发生错误的关键领域。

我对 json 对象的嵌套方式感到困惑。如果我是正确的,我想要的目标的层次结构是:对象(主要对象)-> 对象(数据)-> 数组(newReleases)-> 字符串(prId)。话虽如此,我的印象是我的 self.posts = results.data.newReleases 将直接针对 newReleases 数组(我想要),然后将其打印在 contentView 文本(networkManager.posts[0].prID)

声明列表的内容视图:

struct ContentView: View {
    
    @ObservedObject var networkManager = NetworkManager()
    
    var body: some View {
        
        NavigationView {
                
            List{
                Text(networkManager.posts[0].prID)
            }
                
                .navigationTitle("Json Test")
            }
        .onAppear{
            self.networkManager.fetchData()
        }
    }
}

这是格式化的 JSON 数据的照片。

JSON Data

这就是我在应用中定义数据的方式:

// MARK: - Results
struct Results: Codable {
    let data: DATAClass

    enum CodingKeys: String, CodingKey {
        case data = "DATA"
    }
}

// MARK: - DATAClass
struct DATAClass: Codable {
    let newReleases, exclusives, preorders, backIssues: [BackIssue]
}

// MARK: - BackIssue
struct BackIssue: Codable {
    let totalcount: String
    let sectionName: SectionName
    let sectionLink, prID, prParentid, prTtle: String
    let prPrice, prLprice, prSimg, prBimg: String

    enum CodingKeys: String, CodingKey {
        case totalcount
        case sectionName = "section_name"
        case prID = "pr_id"
        case prTtle = "pr_ttle"
        case prPrice = "pr_price"
        
    }
}


}

enum SectionName: String, Codable {
    case featuredNewReleases = "FEATURED_NEW_RELEASES"
    case recommendedBackIssues = "RECOMMENDED_BACK_ISSUES"
    case recommendedPreOrders = "RECOMMENDED_PRE_ORDERS"
}

这是我尝试解码 json 对象的地方:

@Published var posts = !! [BackIssue]() !!
    
    func fetchData() {
        if let url = URL(string:" https://www.midtowncomics.com/wcfmt/services/product.svc/load-featured-sections?apiKey=&mtUser=&mtPass=&sh_id=76367&pgn=home&app_id") {
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { data, response, error in
                 if error == nil {
                    let decoder = JSONDecoder()
                    if let safeData = data {
                        do {
                          let results = try decoder.decode(Results.self, from: safeData)
                            DispatchQueue.main.async {
                                !! self.posts = results.data.newReleases !! 
                            }
                            
                            
                        } catch {
                            print(error)
                        }
                       
                    }
                    
                }
            }
            task.resume()
        }
    }
}

【问题讨论】:

  • 您没有显示您尝试解码数据的位置,或者您在说时遇到的错误。你能澄清一下你遇到了什么问题吗?
  • 对不起。我完成了忘记添加它。我现在已经更新了我尝试解码信息的位置。
  • 您还没有说是否遇到错误或预期结果与您遇到的情况。
  • @jnpdx 嘿,对不起。我已经更新了帖子并澄清了我的问题。我遇到了一个错误:致命错误:尝试在内容视图中显示数据时索引超出范围。这基本上就是我目前正在尝试做的所有事情;正确定位数据并显示它。所以我不确定是我的方法不对,还是我定位数据的方式。

标签: json swiftui


【解决方案1】:

永远不要在 SwiftUI 视图的渲染区域中通过硬编码索引获取项目。如果数组为空,则代码可靠地崩溃。

通过更换安全地获取物品

Text(networkManager.posts[0].prID)

Text(networkManager.posts.first?.prID ?? "n/a")

如果数组为空则跳过ForEach 循环更好。

【讨论】:

  • 感谢您的回复。因此,如果我将“n/a”视为返回值,我是否正确地假设这意味着我什至没有针对信息?
  • 基本上是的。发生崩溃是因为当您异步获取数据时第一次呈现视图时数组(仍然)为空。使用不会崩溃的ForEach 循环。
  • 这还不够吗? “列表(networkManager.posts){在HStack中发布{文本(post.prID)}}”。 ...它不适合我。但我不明白为什么。我的问题在于我如何定位数据?或者我是如何尝试显示它的?...基本上我要做的就是能够访问 Json 对象级别内的数据,以便我最终可以将对象显示为视图中的项目.
  • ListForEach 在这种情况下执行相同的操作。在 SwiftUI 中,强烈建议将异步内容放入 @ObservableObject。请注意,对于@ObservedObject负责生命周期。
  • 我很困惑,这不是我的设置吗?如果我误解了您的解释,我深表歉意。我只是很难理解我的错误在哪里。有没有什么可能的方式可以为我提供一个在内容视图上显示单个 prID 数据的示例?如果我能看到它应该是什么样子,我就无法知道我哪里出错了。
猜你喜欢
  • 1970-01-01
  • 2015-08-17
  • 2015-07-16
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2012-08-05
相关资源
最近更新 更多