Инициализатор для условного связывания должен иметь необязательный тип, а не 'T.ID' - PullRequest
0 голосов
/ 25 января 2020

У меня есть следующий класс с функциями Firebase:

class FIRFirestoreService {

private init() {}
static let shared = FIRFirestoreService()

func configure() {
    FirebaseApp.configure()
}

private func reference(to collectionReference: FIRCollectionReference) -> CollectionReference {
    return Firestore.firestore().collection(collectionReference.rawValue)
}

func create<T: Encodable>(for encodableObject: T,in collectionReference: FIRCollectionReference) {
    do {
        let json = try encodableObject.toJson(excluding: ["id"])
        reference(to: collectionReference).addDocument(data: json)
    } catch {
        print(error)
    }
}

func read<T: Decodable>(from collectionReference: FIRCollectionReference, returning objectType: T.Type, completion: @escaping ([T]) -> Void) {
    reference(to: collectionReference).addSnapshotListener { (snapshot, _) in
        guard let snapshot = snapshot else { return }
        do {
            var objects = [T]()
            for document in snapshot.documents {
                let object = try document.decode(as: objectType.self)
                objects.append(object)
            }
            completion(objects)
        } catch {
            print(error)
        }
    }
}

func update<T: Encodable & Identifiable>(for encodableObject: T, in collectionReference: FIRCollectionReference) {
    do {
        let json = try encodableObject.toJson(excluding: ["id"])
        guard let id = encodableObject.id else { throw MyError.encodingError }
        reference(to: collectionReference).document(id).setData(json)
    } catch {
        print(error)
    }
}

func delete<T: Identifiable>(_ identifiableObject: T, in collectionReference: FIRCollectionReference) {
    do {
        guard let id = identifiableObject.id else { throw MyError.encodingError }
        reference(to: collectionReference).document(id).delete()
    } catch {
        print(error)
    }
}

}

Вот мой файл Encodable + Extension

extension Encodable {
func toJson(excluding keys: [String] = [String]()) throws -> [String : Any] {
    let objectData = try JSONEncoder().encode(self)
    let jsonObject = try JSONSerialization.jsonObject(with: objectData, options: [])
    guard var json = jsonObject as? [String : Any] else { throw MyError.encodingError }

    for key in keys {
        json[key] = nil
    }

    return json
}

}

А вот файл снимка + расширения

extension DocumentSnapshot {
func decode<T: Decodable>(as objectType: T.Type, includingId: Bool = true) throws -> T {
    var documentJson = data()
    if includingId {
        documentJson!["id"] = documentID
    }

    let documentData = try JSONSerialization.data(withJSONObject: documentJson, options: [])
    let decodedObject = try JSONDecoder().decode(objectType, from: documentData)

    return decodedObject
}

}

В двух функциях (обновление и удаление) следующая строка:

guard let id = encodableObject.id else { throw MyError.encodingError }

Получает помеченный с помощью следующее:

Инициализатор для условного связывания должен иметь необязательный тип, а не 'T.ID'

Почему это так и как мне его подогнать?

1 Ответ

1 голос
/ 25 января 2020

Ошибка довольно очевидна, это означает, что объект guard не является необязательным.

На самом деле Идентифицируемый протокол требует необязательного свойства id, поэтому замените

guard let id = identifiableObject.id else { throw MyError.encodingError }

с

let id = identifiableObject.id
...