#swift #swiftui
#swift #swiftui
Вопрос:
Я разработчик Android, и я начал изучать Swift. До сих пор мне удавалось делать все, что я хотел, но мне трудно слушать обновления SwiftUI
.
Я реализовал сервис, который использует Firestore
для чтения из базы данных. Эта служба является ObservableObject
. Внутри службы у меня есть переменная, которая помечена как @Published
:
@Published var events = [Event]()
Я внедрил Карты Google, и я хочу извлекать эти события и что-то с ними делать, но я не знаю, как прослушивать и что-то делать, когда вызов выполнен.
Класс Карт Google:
import SwiftUI
import GoogleMaps
struct GoogleMapsView: UIViewRepresentable {
@ObservedObject var databaseService = DatabaseService()
func makeUIView(context: Self.Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: 45.764375, longitude: 24.994272, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
// Here I think I call .getEvents
databaseService.getEvents()
return mapView
}
func updateUIView(_ mapView: GMSMapView, context: Context) {
// Listen to events update and update them like this, but I don't know how...
for event in self.databaseService.events {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: event.lat, longitude: event.long)
marker.title = event.title
marker.snippet = event.title
marker.map = mapView
}
}
}
struct GoogleMapsView_Previews: PreviewProvider {
static var previews: some View {
GoogleMapsView()
}
}
И мое SwiftUI
мнение:
import SwiftUI
struct CommunicationsView: View {
@ObservedObject var databaseService = DatabaseService()
var body: some View {
TabView() {
GoogleMapsView()
.edgesIgnoringSafeArea(.top)
.tabItem {
Image(systemName: "leaf.fill")
Text("Campanii")
}
}.accentColor(.green)
}
}
struct CommunicationsView_Previews: PreviewProvider {
static var previews: some View {
CommunicationsView()
}
}
Кроме того, вот мой сервис:
class DatabaseService : ObservableObject {
let db: Firestore
@Published var events = [Event]()
init() {
db = Firestore.firestore()
}
func getEvents() -> Void {
var tempoEvents = [Event]()
db.collection(DatabaseName.CAMPAIGNS.rawValue).getDocuments { (query: QuerySnapshot?, error: Error?) in
for document in query!.documents {
let data = document.data()
let title = data["title"] as? String ?? ""
let details = data["details"] as? String ?? ""
let lat = data["lat"] as? Double ?? 0.0
let long = data["long"] as? Double ?? 0.0
let date = data["date"] as? Date ?? Date()
let author = data["author"] as? String ?? ""
tempoEvents.append(Event(id: document.documentID, title: title, details: details, lat: lat, long: long, date: date, author: author))
}
self.events.append(contentsOf: tempoEvents)
}
}
}
Ответ №1:
Вам нужно поместить
@ObservedObject var databaseService = DatabaseService()
только внутри CommunicationsView
с
GoogleMapsView(events:self.databaseService.events)
и добавьте свойство var events = [Event]()
внутри GoogleMapsView
struct GoogleMapsView: UIViewRepresentable {
var events = [Event]()
......
for event in self.events {
}
}
наконец init
, в DatabaseService
init() {
db = Firestore.firestore()
self.getEvents()
}
Комментарии:
1. Но когда мне вызывать DatabaseService.getEvents? должен ли я использовать что-то вроде. onAppear?
2. это другой способ также или внутри
init
3. В моем случае карта отображается до того, как служба завершит выборку, что мне делать?
4. вам нечего делать, вот как происходит асинхронный процесс — вы можете показать загрузку, если вам нужно