本文介绍了如果某些东西符合 Codable,它会永远无法编码或解码吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道符合 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.

例如,如果我有一个名为 Bookstruct:

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,它会永远无法编码或解码吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 17:13