首页 > 解决方案 > 如何在 SwiftUI 列表中显示字典数组?

问题描述

在通过迁移旧 ObjC 应用程序的一部分来学习 Swift 几个月后,我期待在纯 Swift 中启动一个新应用程序 - 我希望使用纯 Swift 基类将减少展开和其他桥接恶作剧.

然而,很快我发现自己面临着类似的问题。

我想从 Web 服务中读取一些 JSON,并显示在使用 SwiftUI 实现的列表中 - 应该很简单,对吧?

数据(实际上是从 Twitter API 读取的)进来,我反序列化它,

    do {
        if let results = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments  ) as? [String: Any] {
            print(results)
            if let followers = results["users"] as? [[String: Any]] {
                print (followers.count)
                print("followers class \(type(of: followers))")
            } else {
                print(results["errors"])
            }
        }
    } catch let error as NSError {
        print(error.localizedDescription)
    }

你会看到我打印了追随者的类别,这表明,

followers class Array<Dictionary<String, Any>>

...一个不错的字典数组,使用 Swift 基类。这似乎是通过 SwiftUI 中的 List 呈现的合理数据结构。但是,它似乎并不那么简单,因为数据元素需要是可识别的(足够公平),但我没有每个元素的结构,而且我不希望将数组处理成携带标识符的结构数组。

进行了一些研究,似乎有一个可用的解决方案,因为我可以使用数组初始化 List,如下所示,

var body: some View {
    List (twitter.followers!, id: \.self) { follower in // <<< Compilation error
        Text("\(follower["name"])")
    }
}

但是,该代码在标记行上给出了编译错误,

协议类型“Any”不能符合“Hashable”,因为只有具体类型才能符合协议

我认为问题在于编译器将追随者视为“任何”,而不是数组,但为什么呢?

顺便说一句,我已经看到了这个问题的答案,但似乎 List 初始化程序应该是一个更优雅的解决方案,如果我能让它工作......

标签: swiftswiftui

解决方案


您必须为追随者/用户创建一个结构并将其声明为Decodableand Identifiable

然后,您将能够使用JSONDecoder将数据从结构读取到数组中。

因此,您的 twitter.followers 将是一组可识别的对象,您将能够在ForEach().


推荐阅读