问题描述
我想知道符合 Codable
的对象在编码或解码过程中是否会导致错误.我觉得好像遵守协议确保永远不会抛出错误.
I was wondering if an object which conforms to Codable
can ever cause an error while in the process of being encoded or decoded. I feel as though conforming to the protocol ensures that an error can never be thrown.
例如,如果我有一个名为 Book
的 struct
:
For example if I have a struct
called Book
:
struct Book: Codable, Identifiable {
@DocumentID var id: String?
var name: String
}
这个 struct
永远 是否可以编码或解码失败?例如,如果我这样做:
Can this struct
ever fail to be encoded or decoded?For example if I do:
try! docRef.setData(from: book) { error in _ }
如果 Book
符合 Codable
,我认为这不会永远同步抛出错误.
I don't think this can ever throw an error synchronously if Book
conforms to Codable
.
同样,
try! docRef.data(as: Book.self)
不应该永远抛出,因为Book
再次符合Codable
should never throw because, again, Book
conforms to Codable
如果我错了,Book
在编码或解码时可能会失败,请解释在什么条件/情况下可能会发生.
If I'm wrong and Book
may fail while being Encoded or Decoded please explain under what conditions/circumstances that might happen.
提前致谢!
推荐答案
当你在 Firestore 的上下文中提出这个问题时,除了 Ralf 在他的回答中提到的内容之外,我想添加一些更多的细节.
As you asked this question in the context of Firestore, I'd like to add some more details in addition to what Ralf mentioned in his answer.
在解码 Firestore 文档时,有多种情况可能会导致映射错误,这就是您应该准备好处理它们的原因.
When decoding a Firestore document, there are a number of situations that might in a mapping error, which is why you should be prepared to handle them.
例如:
- 您的结构可能需要一个字段(即它是非可选的),但 Firestore 文档中缺少该字段.如果您有其他应用(Android、Web,甚至是您的 iOS 应用的先前版本)写入同一文档,但使用先前版本的架构,则可能会发生这种情况
- 文档中的一个(或多个)属性可能与您的结构具有不同的数据类型.
以下代码片段包含针对这些和其他情况的大量错误处理(请注意,您需要根据个人情况调整处理这些错误的方式 - 您可能希望也可能不想显示用户可见的错误消息,例如).代码取自我的文章 Mapping Firestore Data in Swift - The Comprehensive指南.
The following code snippet contains extensive error handling for these and other cases (please be aware that you need to adjust how to handle those errors to your individual situation - you might or might not want to display a user-visible error message, for example). The code is taken from my article Mapping Firestore Data in Swift - The Comprehensive Guide.
class MappingSimpleTypesViewModel: ObservableObject {
@Published var book: Book = .empty
@Published var errorMessage: String?
private var db = Firestore.firestore()
func fetchAndMap() {
fetchBook(documentId: "hitchhiker")
}
func fetchAndMapNonExisting() {
fetchBook(documentId: "does-not-exist")
}
func fetchAndTryMappingInvalidData() {
fetchBook(documentId: "invalid-data")
}
private func fetchBook(documentId: String) {
let docRef = db.collection("books").document(documentId)
docRef.getDocument { document, error in
if let error = error as NSError? {
self.errorMessage = "Error getting document: \(error.localizedDescription)"
}
else {
let result = Result { try document?.data(as: Book.self) }
switch result {
case .success(let book):
if let book = book {
// A Book value was successfully initialized from the DocumentSnapshot.
self.book = book
self.errorMessage = nil
}
else {
// A nil value was successfully initialized from the DocumentSnapshot,
// or the DocumentSnapshot was nil.
self.errorMessage = "Document doesn't exist."
}
case .failure(let error):
// A Book value could not be initialized from the DocumentSnapshot.
switch error {
case DecodingError.typeMismatch(let type, let context):
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
case DecodingError.valueNotFound(let type, let context):
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
case DecodingError.keyNotFound(let key, let context):
self.errorMessage = "\(error.localizedDescription): \(context.debugDescription)"
case DecodingError.dataCorrupted(let key):
self.errorMessage = "\(error.localizedDescription): \(key)"
default:
self.errorMessage = "Error decoding document: \(error.localizedDescription)"
}
}
}
}
}
}
如果您对 Firestore 如何实现 Codable 协议感到好奇,请前往 源代码.例如,搜索 DecodableError
将显示可能发生哪些错误条件以及原因.
If you're curious about how Firestore implements the Codable protocol, head over to the source code. For example, searching for DecodableError
will show how exactly which error conditions might occur, and why.
这篇关于如果某些东西符合 Codable,它会永远无法编码或解码吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!