Существует еще более простой способ добиться этого с помощью поддержки Codable, которую мы недавно добавили в Firestore:
Добавьте модуль FirebaseFirestoreSwift
:
# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'
target 'MyAwesomeApp' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for MyAwesomeApp
pod 'Firebase/Analytics'
pod 'Firebase/Firestore'
pod 'FirebaseFirestoreSwift'
end
import FirebaseFirestoreSwift
struct City: Codable, Identifiable {
@DocumentID var id: String? = UUID().uuidString
let name: String
let state: String
let country: String
let isCapital: Bool
let population: Int64
// you only need CodingKeys if your attribute names in Firestore differ from the property names on your struct!
}
Используя Оболочка свойства @DocumentID
, вы указываете службе поддержки Firestore Codable, что хотите, чтобы она отображала идентификатор документа в поле id
. Также обратите внимание, что - поскольку структура City
реализует Identifiable
- вы сможете использовать ее в SwiftUI ListView
.
Затем в модели представления используйте queryDocumentSnapshot.data(as:)
для извлечения и отображения данные в безопасном виде:
import FirebaseFirestore
class CitiesViewModel: ObservableObject {
@Published var cities = [City]()
private var db = Firestore.firestore()
private var listenerRegistration: ListenerRegistration?
deinit {
unregister()
}
func unregister() {
if listenerRegistration != nil {
listenerRegistration?.remove()
}
}
func fetchData() {
unregister()
listenerRegistration = db.collection("cities").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.cities = documents.compactMap { queryDocumentSnapshot -> City? in
return try? queryDocumentSnapshot.data(as: City.self)
}
}
}
}