Ios Can';t在单独的变量/常量中从CLLocationManager获取坐标

Ios Can';t在单独的变量/常量中从CLLocationManager获取坐标,ios,swift,swift3,core-location,Ios,Swift,Swift3,Core Location,我试图在Swift中使用函数中的值设置变量/常量,该函数在应用程序打开时查找用户的当前位置。当我取消对print函数的注释时,它会成功地打印坐标,但我无法访问函数外部的值 我目前将此作为代码的一部分,该代码位于MainVC.swift文件中,作为MainVC类的一部分: import UIKit import MapKit import CoreLocation class MainVC: UIViewController, CLLocationManagerDelegate { //

我试图在Swift中使用函数中的值设置变量/常量,该函数在应用程序打开时查找用户的当前位置。当我取消对print函数的注释时,它会成功地打印坐标,但我无法访问函数外部的值

我目前将此作为代码的一部分,该代码位于MainVC.swift文件中,作为MainVC类的一部分:

import UIKit
import MapKit
import CoreLocation

class MainVC: UIViewController, CLLocationManagerDelegate {
    //Map
    @IBOutlet weak var map: MKMapView!

    let manager = CLLocationManager()
    let coordinates = locationManager()
    //I've also tried using let coordinates = currentCoords

    override func viewDidLoad() {
        super.viewDidLoad()

        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.requestWhenInUseAuthorization()
        manager.startUpdatingLocation()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) -> String {
        let location = locations[0]

        let span:MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
        let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
        let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
        map.setRegion(region, animated: true)
        lat = String(myLocation.latitude)
        long = String(myLocation.longitude)
        let currentCoords:String = "\(lat);\(long)"

        //print(currentCoords)
        self.map.showsUserLocation = true

        return currentCoords
    }
}
然而,我面临着这个错误:

“无法在属性初始值设定项中使用实例成员‘locationManager’;属性初始值设定项在‘self’可用之前运行。”

当我更改代码并使用

let coordinates = currentCoords
我收到另一个错误,显示:

“使用未解析标识符'currentCoords'”


我还尝试过使用lazy var和lazy let。

您应该可以访问locationManager.location?。按照我的按钮单击方法进行协调:

import UIKit
import MapKit

class ViewController: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate {

    let locationManager = CLLocationManager()

    @IBAction func buttonClick(_ sender: Any) {
        let location = locationManager.location?.coordinate
        let lat:Double = (location?.latitude)!
        let lon:Double = (location?.longitude)!
        print(lat,lon)
    }

    @IBOutlet weak var mapView: MKMapView!

        override func viewDidLoad() {
        super.viewDidLoad()

        mapView.delegate = self
        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow

        locationManager.delegate = self
        locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters
        locationManager.desiredAccuracy = kCLLocationAccuracyBest

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("viewDidAppear")
        // status is not determined
        if CLLocationManager.authorizationStatus() == .notDetermined {
            locationManager.requestAlwaysAuthorization()
        }
            // authorization were denied
        else if CLLocationManager.authorizationStatus() == .denied {
            showAlert("Location services were previously denied. Please enable location services for this app in Settings.")
        }
            // we do have authorization
        else if CLLocationManager.authorizationStatus() == .authorizedAlways {
            locationManager.startUpdatingLocation()
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("didUpdateLocations")
        print(locations.last?.coordinate)
    }

    func showAlert(_ title: String) {
        let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
            alert.dismiss(animated: true, completion: nil)
        }))
        self.present(alert, animated: true, completion: nil)

    }
}

这就是定义公共变量的方式

let coordinates:CLLocation = nil
然后在didUpdateLocations中,使用位置数组的最后一个元素指定坐标变量。然后你可以在任何地方使用它。 请记住,didUpdateLocations可能会在几秒钟后被调用,因此公共变量坐标将在几秒钟后填充

func coordinatesBecomeAvailable() {
    // Here you can print your coordinates or start using them for the first time
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
 let firstTime:Bool = (coordinates == nil)
 coordinates = locations[0]
 if (firstTime) // This is first time this function is called
     coordinatesBecomeAvailable()
 ......
 < Rest of your code here >
 ......
 < This function does have any return value! no String nothing >
 }
func坐标变得可用(){
//在这里,您可以打印坐标或首次使用坐标
}
func locationManager(manager:CLLocationManager,didUpdateLocations位置:[CLLocation]){
让我们第一次:Bool=(坐标==nil)
坐标=位置[0]
if(firstTime)//这是第一次调用此函数
协调变得可用()
......
<此处的其余代码>
......
<此函数没有任何返回值!无字符串无>
}
您只需要检查坐标的值是否为零。 或者,您可以在didUpdateLocations中检查这是否是第一次调用此委托方法。
这不是初始化和使用location manager的最有效和最完整的方法,我假设您只是发布了与问题相关的代码。

您需要为发布的代码提供更多的上下文。您的错误不是来自初始值设定者吗?从出现错误的初始值设定项粘贴代码。@rmaddy对此表示抱歉,在最初发布时忘记添加它,用一些上下文更新了主帖子,希望能有所帮助。发布包含您发布的代码的整个函数。请注意,“坐标”是位置管理器实例的可怕名称。@duncac这是整个函数,我在应用程序中使用了不同的标识符,我在发布时为了可读性而更改了它。我已经在原来的帖子中添加了更多的信息,希望能对你有所帮助。嗨,谢谢你的帖子。我试着这样做,但出于某种原因,它不喜欢这种方法,我明天一上MacBook就会发布这种方法的错误。我得到以下错误:类型的值“(MainVC)->(CLLocationManager,[CLLocation])->String'没有成员'location'我在
let location=locationManager.location?.coordinate
linear上找到了它你在使用swift 3.0吗?我应该,使用Xcode 8并将部署目标设置为iOS 10I时,我更改了代码并添加了此项,但当我打印坐标时,它显示nilI更改了代码,以便您知道坐标可用时何时打印。@robycyr由于某些原因,我仍然得到nil我更改了didUpdateLocations函数并将“locations.last”替换为“位置[0]”与您的代码类似,现在您可以在该行代码中放置断点,并在调试模式下一次执行一行代码,查看“坐标”是否获得值。从这一点开始就是调试的问题。您可以使用“coordinates BecomeAvailable”函数打印或使用变量的第一次使用。