在我当前的项目中,我希望能够在地图上显示用户的当前位置。
我已经通过Apple提供的requestLocation方法实现了此功能,但是问题是我的代码继续运行而没有等待requestLocation函数完成。

流程是这样的:首先,我调用positionController.setPositionViaLocationData()函数,该函数处理requestLocation方法的设置和执行。最后,它接收坐标并将其存储在userPositionPositionController成员中。
在下一行代码中,我想通过userPosition访问PositionController,但这是我的问题:

线...

var userPosition = positionController.getPosition()

...在positionController.setPositionViaLocationData()完成之前执行,因此它采用存储在userPosition中的默认值。

我如何让我的代码在执行之前等待positionController.setPositionViaLocationData()var userPosition = positionController.getPosition()
我已经读过有关Closures和CompletionManagers的资料,但是我没有这些资料对我有用。

这是两个类的代码,首先是调用函数的ViewController:
import UIKit
import GoogleMaps
import CoreLocation

class MapViewController: UIViewController, CLLocationManagerDelegate {

    let positionController = PositionController()

    override func viewDidLoad() {
        super.viewDidLoad()

        positionController.setPositionViaLocationData()
        var userPosition = positionController.getPosition()
        setUserPositionMarkerOnMapAndShowMap(userPositionLatitude: userPosition.userLatitude, userPositionLongitude: userPosition.userLongitude)

    }

    func setUserPositionMarkerOnMapAndShowMap(userPositionLatitude: Double, userPositionLongitude: Double){
        let camera = GMSCameraPosition.camera(withLatitude: userPositionLatitude,
                                              longitude: userPositionLongitude, zoom:3)
        let mapView = GMSMapView.map(withFrame: CGRect.zero, camera:camera)
        let marker = GMSMarker()

        self.view = mapView
        marker.snippet = "Munich"
        marker.appearAnimation = GMSMarkerAnimation.pop
        marker.map = mapView

        self.view = mapView
    }

}

现在我的PositionController类:
import Foundation
import CoreLocation

class PositionController: CLLocationManager, CLLocationManagerDelegate {

    let locationManager: CLLocationManager
    var userPosition = Position(longitude: 0,latitude: 0)

    override init() {
        self.locationManager = CLLocationManager()
        print("---------------Init---------------------------")
    }

    func setPositionViaLocationData(){

        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
        locationManager.requestLocation()
    }

    func setPosition(longitude: Double, latitude: Double){
        userPosition.longitude = longitude
        userPosition.latitude = latitude
    }

    func getPosition() -> (userLongitude: Double, userLatitude: Double){
        return (userPosition.longitude, userPosition.latitude)
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error)
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        let locValue:CLLocationCoordinate2D = manager.location!.coordinate
        print("locations = \(locValue.latitude) \(locValue.longitude)")
        userPosition.latitude = locValue.latitude
        userPosition.longitude = locValue.longitude
    }
}

最佳答案

您可以使用委托来通知MapViewController用户位置已更新。

您可以在PositionController类定义上方添加下一个协议

protocol PositionControllerDelegate: class {
  func didUpdatePosition(_ newPosition: Position)
}

然后向PositionController添加一个新的可选属性
weak var delegate: PositionControllerDelegate?
然后调用委托方法:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let locValue: CLLocationCoordinate2D = manager.location!.coordinate
    print("locations = \(locValue.latitude) \(locValue.longitude)")
    userPosition.latitude = locValue.latitude
    userPosition.longitude = locValue.longitude
    delegate?.didUpdatePosition(userPosition)
}

在MapViewController端,您只需实现协议并将self分配给PositionController的委托。
override func viewDidLoad() {
    super.viewDidLoad()

    positionController.setPositionViaLocationData()
    positionController.delegate = self
    var userPosition = positionController.getPosition()
    setUserPositionMarkerOnMapAndShowMap(userPositionLatitude: userPosition.userLatitude, userPositionLongitude: userPosition.userLongitude)
}

extension MapViewController: PositionControllerDelegate {
  func didUpdatePosition(_ newPosition: Position) {
    //Do whatever you want with the position
  }
}

10-08 06:13