【发布时间】:2020-01-21 13:25:05
【问题描述】:
如果有以下代码,应该将 [String: any] 文档从 Firestore 转换为结构。
当时我调试时所有要求都满足,但返回值是nil。
我尝试将init? 更改为常规init 和guard 上的else { fatalError() }。如果数据有效,这将有效并返回一个有效的结构。
我在使用可失败初始化程序时做错了什么?
这不起作用(总是返回 nil,即使有有效数据):
struct Banner {
let destinationUrl: URL
let imageUrl: URL
let endTime: Date
let startTime: Date
let priority: Int
let trackingKeyClicked: String
let trackingKeyDismissed: String
init?(document: [String: Any]) {
guard
let destinationUrlString = document["destinationUrl"] as? String,
let destinationUrl = URL(string: destinationUrlString),
let imageUrlString = document["imageUrl"] as? String,
let imageUrl = URL(string: imageUrlString),
let priority = document["priority"] as? Int,
let trackingKeyClicked = document["trackingKeyClicked"] as? String,
let trackingKeyDismissed = document["trackingKeyDismissed"] as? String,
let startTime = document["startTime"] as? Date,
let endTime = document["endTime"] as? Date
else { return nil }
self.destinationUrl = destinationUrl
self.imageUrl = imageUrl
self.priority = priority
self.trackingKeyClicked = trackingKeyClicked
self.trackingKeyDismissed = trackingKeyDismissed
self.endTime = endTime
self.startTime = startTime
}
}
// using it like this
let bannerStructs = querySnapshot.documents.map { Banner(document: $0.data()) }
这适用于有效数据(但在错误数据上崩溃而不是返回 nil):
struct Banner {
let destinationUrl: URL
// ...
let endTime: Date
init(document: [String: Any]) {
guard
let destinationUrlString = document["destinationUrl"] as? String,
let destinationUrl = URL(string: destinationUrlString),
// ....
let endTime = document["endTime"] as? Date
else { fatalError() }
self.destinationUrl = destinationUrl
// ...
self.endTime = endTime
}
}
【问题讨论】:
-
如果它在非可选初始化时不起作用并且崩溃,那么初始化失败,您需要调试您所做的字段和强制转换。在你的 else return nil 语句中放置一个断点,它会命中它。使用 Codable 可能会更好
-
看来您正在处理 JSON。为什么你的结构不应该实现 Codable ?
-
“当我调试时,我可以看到所有要求都得到满足” 但是我们看不到,因为您没有显示任何数据。如果失败,返回 nil,那是因为守卫语句失败。我相信运行时,而不是你。
-
你可以使用可选链来代替守卫。您将能够找到确切的问题。
-
我怀疑
startTime或endTime是否会被转换为Date。你可以在你的保护语句的开头设置一个断点,然后点击Step over并检查你的哪些变量没有被强制转换吗?我假设是您的startTime和endTime变量失败,因此返回nil。