简体   繁体   English

Swift中的可解码文档参考

[英]Decodable DocumentReference in Swift

I have a custom model in swift and it has a property of type DocumentReference I'm getting some data from a cloud function and then I'm trying to decode it back to my model. I have a custom model in swift and it has a property of type DocumentReference I'm getting some data from a cloud function and then I'm trying to decode it back to my model.

DocumentReference doesn't conform to Decodable by itself so I'm trying to write an extension for it. DocumentReference本身不符合 Decodable ,因此我正在尝试为其编写扩展。

I can not make it work since I keep getting this error:我无法使它工作,因为我不断收到此错误:

Initializer requirement 'init(from:)' can only be satisfied by a 'required' initializer in the definition of non-final class 'DocumentReference'初始化程序要求“init(from:)”只能由非最终 class“DocumentReference”定义中的“必需”初始化程序满足

Any idea how to make this work?知道如何进行这项工作吗?

My extension:我的扩展:

import Firebase

extension DocumentReference: Decodable {
    public convenience init(from decoder: Decoder) throws {
        //
    }
}

Existing model:现有 model:

struct Notification: Identifiable, CollectionProtocol, DocumentProtocol {
    var id = UUID()

    var documentReference: DocumentReference
    var receiverID: String
    var type: String
    var createdAt: Date
    var requestReference: DocumentReference?
    var request: Request?

    init(document: DocumentSnapshot) {
        self.documentReference = document.reference
        self.requestReference = document["requestReference"] as? DocumentReference ?? Firestore.firestore().document("")
        self.receiverID = document["receiverID"] as? String ?? ""
        self.type = document["type"] as? String ?? ""
        self.createdAt = (document["createdAt"] as? Timestamp)?.dateValue() ?? Date()
    }
}
NS_SWIFT_NAME(DocumentReference)
@interface FIRDocumentReference : NSObject

/** :nodoc: */
- (instancetype)init
    __attribute__((unavailable("FIRDocumentReference cannot be created directly.")));

DocumentReference ( FIRDocumentReference ) cannot be instantiated directly; DocumentReference ( FIRDocumentReference ) 不能直接实例化; it has no available initializers.它没有可用的初始化程序。 To implement the required init, you'd have to do that in the declaration of the class itself.要实现所需的 init,您必须在 class 本身的声明中执行此操作。

If you want to conveniently instantiate custom objects from Firestore data, consider a failable initializer that takes a [String: Any] argument.如果您想方便地从 Firestore 数据实例化自定义对象,请考虑使用[String: Any]参数的可失败初始化程序。 If you just want to encode/decode the reference itself, consider encoding/decoding the String value of the location itself (the collection and document names) and then using that to reconstruct the DocumentReference .如果您只想对引用本身进行编码/解码,请考虑对位置本身的String值(集合和文档名称)进行编码/解码,然后使用它来重建DocumentReference

The class DocumentReference is not final which means that it could possibly be sub-classed but without the sub class conforming to Codable. class DocumentReference 不是最终的,这意味着它可能是子分类但没有符合 Codable 的子 class。 So this would leave to an unknown state if init(from decoder: Decoder) in your extension was called.因此,如果您的扩展程序中的init(from decoder: Decoder)被调用,这将留给未知的 state。

One workaround could be to create a wrapper struct with its own init(from decoder: Decoder) and then do your decoding of DocumentReference there.一种解决方法可能是使用自己的init(from decoder: Decoder)创建一个包装器结构,然后在那里对 DocumentReference 进行解码。

Example:例子:

struct Wrapped: Decodable {
    let docRef: DocumentReference

    public init(from decoder: Decoder) throws {
        let container = try decoder....

        // add the decoding code here for DocumentReference
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM