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 中加载的主要内容,如果未能解决你的问题,请参考以下文章