【发布时间】:2021-01-25 03:59:42
【问题描述】:
我尝试使用非数组 @Published 项创建一个 ObservableObject。但是,我仍然不知道该怎么做。我尝试使用 ?这样做。但是当我在Text((details.info?.name)!) 这样的视图中显示它并返回Thread 1: Swift runtime failure: force unwrapped a nil value 时,我不知道问题是什么以及如何解决。我创建可观察对象类的方法是否正确?
class ShopDetailJSON: ObservableObject {
@Published var info : Info?
init(){load()}
func load() {
URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("No data in response: \(error?.localizedDescription ?? "Unknown error").")
return
}
if let decodedShopDetails = try? JSONDecoder().decode(ShopDetail.self, from: data) {
DispatchQueue.main.async {
self.info = decodedShopDetails.info!
}
} else {
print("Invalid response from server")
}
}.resume()
}
}
struct Info : Codable, Identifiable {
let contact : String?
let name : String?
var id = UUID()
enum CodingKeys: String, CodingKey {
case contact = "contact"
case name = "name"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
contact = try values.decodeIfPresent(String.self, forKey: .contact)
name = try values.decodeIfPresent(String.self, forKey: .name)
}
}
struct ShopDetail : Codable {
let gallery : [Gallery]?
let info : Info?
enum CodingKeys: String, CodingKey {
case gallery = "gallery"
case info = "info"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
gallery = try values.decodeIfPresent([Gallery].self, forKey: .gallery)
info = try values.decodeIfPresent(Info.self, forKey: .info)
}
}
示例 JSON 数据
{
"gallery": [],
"info": {
"contact": "6012345678",
"name": "My Salon",
}
}
【问题讨论】:
-
你不需要实现
.init(from:)或自定义CodingKey——只要符合Decodable/Encodable(或Codable)就足够了,即struct ShopDetail: Codable { var gallery: [Gallery]?; var info: Info? }。 ..除此之外,您尝试在nil值上使用!,您会收到此错误。为什么这个值是 nil 很难说,因为我们不知道你正在解码的 JSON 是什么样的 -
@NewDev 使用示例 json 编辑
-
数据不会是nil,至少会是一个空字符串""
-
如果示例 JSON 是正确的,那么您不需要将
ShopDetail.Info设为可选,而ShopDetail.gallery可以只是[Gallery]- 不是可选数组。另外,避免使用!强制展开。很难确定错误是什么,因为您没有显示错误实际发生的位置。我的猜测是你试图在加载之前访问ShopDetailJSON.info,但它失败了。如果是这样,请输入条件:if let info = details.info { Text(info.name) }
标签: swift swiftui observableobject