Декодируемая ссылка на документ в Swift - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть своя модель в swift, и у нее есть свойство типа DocumentReference Я получаю некоторые данные из облачной функции и затем пытаюсь декодировать ее обратно в мою модель.

DocumentReference не соответствует Decodable сам по себе, поэтому я пытаюсь написать для него расширение.

Я не могу заставить его работать, так как я получаю эту ошибку:

Требование инициализатора 'init (from :)' может быть удовлетворено только 'обязательным' инициализатором в определении не финального класса 'DocumentReference'

Есть идеи, как заставить эту работу работать?

Мое расширение:

import Firebase

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

Существующая модель:

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()
    }
}

Ответы [ 2 ]

1 голос
/ 04 апреля 2020

Класс DocumentReference не является окончательным, что означает, что он может быть подклассифицирован, но без подкласса, соответствующего Codable. Таким образом, это привело бы к неизвестному состоянию, если в вашем расширении был вызван init(from decoder: Decoder).

Одним из обходных путей может быть создание структуры-оболочки со своим собственным init(from decoder: Decoder), а затем выполнить там декодирование DocumentReference.

Пример:

struct Wrapped: Decodable {
    let docRef: DocumentReference

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

        // add the decoding code here for DocumentReference
    }
}
1 голос
/ 04 апреля 2020
NS_SWIFT_NAME(DocumentReference)
@interface FIRDocumentReference : NSObject

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

DocumentReference (FIRDocumentReference) не может быть создан непосредственно; у него нет доступных инициализаторов. Чтобы реализовать требуемый init, вам нужно сделать это в объявлении самого класса.

Если вы хотите удобно создавать экземпляры пользовательских объектов из данных Firestore, рассмотрите сбойный инициализатор, который принимает аргумент [String: Any] , Если вы просто хотите закодировать / декодировать саму ссылку, рассмотрите возможность кодирования / декодирования значения String самого местоположения (имена коллекции и документа), а затем используйте его для восстановления DocumentReference.

...