Я все еще развиваю свои навыки в SwiftUI, так что спасибо всем опытным разработчикам, которые могут помочь ответить на мой вопрос.
Для контекста я создаю приложение, которое отображает маркеры на карте, а также список маркеров также. Я использую @EnvironmentObject для хранения данных, чтобы был «один источник правды» и чтобы карта и список автоматически обновлялись при изменении данных.
Чтобы получить нужные мне данные, я делаю 2 типа: API-запросы. Один, чтобы получить список местоположений, затем для каждого местоположения я делаю запрос на дополнительную информацию о каждом соответствующем местоположении.
Чтобы обновить установленный мной @EnvironmentObject, мне нужно выполнить все запросы, а затем обновить его из основного потока приложения. Поэтому моя проблема заключается в том, что мне нужно иметь возможность вызывать функцию только после того, как API-запросы завершат Я надеюсь, что кто-то может показать мне, как изменить их, чтобы я мог вызвать функцию после выполнения 2 запросов:
Вот скелет моего файла, который отображает карту и где я делаю мои запросы API: Основная часть находится в 'расширение GMController' внизу
import SwiftUI
import UIKit
import GoogleMaps
import GooglePlaces
import CoreLocation
import Foundation
struct GoogMapView: View {
var body: some View {
GoogMapControllerRepresentable()
}
}
class GoogMapController: UIViewController, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var mapView: GMSMapView!
let defaultLocation = CLLocation(latitude: 42.361145, longitude: -71.057083)
var zoomLevel: Float = 15.0
let marker : GMSMarker = GMSMarker()
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.distanceFilter = 50
locationManager.startUpdatingLocation()
locationManager.delegate = self
let camera = GMSCameraPosition.camera(withLatitude: defaultLocation.coordinate.latitude, longitude: defaultLocation.coordinate.longitude, zoom: zoomLevel)
mapView = GMSMapView.map(withFrame: view.bounds, camera: camera)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.setMinZoom(14, maxZoom: 20)
mapView.settings.compassButton = true
mapView.isMyLocationEnabled = true
mapView.settings.myLocationButton = true
mapView.settings.scrollGestures = true
mapView.settings.zoomGestures = true
mapView.settings.rotateGestures = true
mapView.settings.tiltGestures = true
mapView.isIndoorEnabled = false
marker.position = CLLocationCoordinate2D(latitude: 42.361145, longitude: -71.057083)
marker.title = "Boston"
marker.snippet = "USA"
marker.map = mapView
view.addSubview(mapView)
}
// Handle incoming location events.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location: CLLocation = locations.last!
print("Location: \(location)")
let camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude, longitude: location.coordinate.longitude, zoom: zoomLevel)
mapView.animate(to: camera)
}
// Handle authorization for the location manager.
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted:
print("Location access was restricted.")
case .denied:
print("User denied access to location.")
// Display the map using the default location.
mapView.isHidden = false
case .notDetermined:
print("Location status not determined.")
case .authorizedAlways: fallthrough
case .authorizedWhenInUse:
print("Location status is OK.")
}
}
// Handle location manager errors.
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.stopUpdatingLocation()
print("Error: \(error)")
}
}
// UIViewControllerExtension
extension GMController {
func requestAndCombineGData(location: CLLocation, radius: Int) {
// Clears map of markers
self.mapView.clear()
// vvv THIS IS WHERE I AM TRYING TO CALL THE REQUESTS IN SUCCESSION AND THEN CALL A FUNCTION AFTER THE REQUESTS ARE FINISHED vvv
// Calls 'Nearby Search' request
googleClient.getGooglePlacesData(location: location, withinMeters: radius) { (response) in
print("Made Nearby Search request. Returned response here:", response)
// loops through each result from the above Nearby Request' to get the 'place_id' and make 'Place Details'
for location in response.results {
// Calls 'Place Details' request
self.googleClient.getGooglePlacesDetailsData(place_id: location.place_id) { (detailsResponse) in
print("GMV returned - detailsResponse.result - ", detailsResponse.result)
}
}
}
}
}
struct GoogMapControllerRepresentable: UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<GMControllerRepresentable>) -> GMController {
return GMController()
}
func updateUIViewController(_ uiViewController: GMController, context: UIViewControllerRepresentableContext<GMControllerRepresentable>) {
}
}
Кто-нибудь знает, как я могу изменить свой код, чтобы я мог вызывать функцию только после выполнения всех запросов API, которая может использовать данные из запросов?