如何获取位置坐标以在另一个类中更新?

时间:2016-03-22 17:54:42

标签: ios swift core-location

我更好地组织我的应用程序,并且在使用CoreLocation的类中遇到问题。我的应用程序检测到iBeacon,然后将其坐标发送到API。

在AppDelegate中,我调用RunLocation()。RunGPS()触发createLocationManager,触发createLocationManager更新坐标并将其发送到API。我的控制台输出打印出应该通过的所有内容"更新位置"。然后没有任何关于经度和纬度的信息让我相信我已经搞砸了一些东西,但我不知道是什么。

当我把它笨拙地放在ViewController中时,它就可以工作了。我现在认为我已经搞砸了一些事情,因为它被分成了不同的课程。

相关代码:

    func runGPS(){
        print("Running GPS")
        createLocationManager(startImmediately: true)
    }

    func createLocationManager(startImmediately startImmediately: Bool){
        locationManager = CLLocationManager()
        onSwitch = true
        if let manager = locationManager
        {
            print("Successfully created the location manager")
            manager.delegate = self
            if startImmediately
            {
                if onSwitch == true {
                    manager.startUpdatingLocation()
                    print("Updating Location")
                }else{
                    print("Off")
                }
            }
        }
    }

    func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation){
//        Stop updating location is onSwitch is false. If true, user has called for help. Turn on GPS and execute a post to the API
        if onSwitch == false
        {
            locationManager.stopUpdatingLocation()
            print("Location updates off")
        }
        else
        {
            loadCoreData()
            loadUser()
            print("Updating location")

            let latitude:String = "\(newLocation.coordinate.latitude)"
            let longitude:String = "\(newLocation.coordinate.longitude)"

            print("Latitude = \(newLocation.coordinate.latitude)")
            print("Longitude = \(newLocation.coordinate.longitude)")

            //Posting to the API which generates a map and sends SMS messages
            post(["device_id":"\(deviceID)", "sender":"\(username)", "longitude":"\(longitude)", "latitude":"\(latitude)", "contacts":"\(phoneArray)"], url: "http://ring-api.herokuapp.com/api/v1/alerts")

            //API has been called so stop posting
            onSwitch = false
        }
    }

控制台输出:

2016-03-22 10:39:14.689 MangosBeta0.4[1531:677382] You entered the region
Running GPS
Successfully created the location manager
Updating Location

3 个答案:

答案 0 :(得分:2)

如果将位置管理器保留为实例变量,则可以通过访问当前应用程序的委托属性从任何地方访问它们。

if let delegate = UIApplication.sharedApplication().delegate as? AppDelegate {
  let manager = delegate.locationManager
}

现实情况是,如果您正在尝试改进您的应用程序架构,我个人不会将位置逻辑放在您的应用程序委托中。这对我来说感觉错误。如果我是你,我会创建一个LocationManager单例类来解决这两个问题。

如果你需要实时更新依赖类,我会发布一个NSNotification并在需要更新的类上监听它。

答案 1 :(得分:1)

您的委托方法未被调用。我想在调用startUpdatingLocation之前您错过了调用requestAlwaysAuthorization()requestWhenInUseAuthorization()。编辑info.plist文件以添加以下NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription

答案 2 :(得分:0)

一种可管理的方法是将位置管理分解为一个单独的类,可能称为LocationController,并在init方法中将其实例化为单例实例。

public class LocationController {
  static let sharedInstance = LocationController()

}

然后,您可以从AppDelegate实例化它,并从您应用中的任何控制器引用它。在您的ApplicationDidFinishLaunchingWithOptions中:

self.locationController = LocationController()

让您的LocationController从locationManager获取回调,然后使用NSNotifications将信息适当地分发到您应用的其他部分。

查看对更新感兴趣的控制器可以注册它们:

func viewDidLoad (...) {
    NSNotificationCenter.defaultCenter().addObserver(self, selector:"locationChanged:", name: "locationChanged", object: nil)
}

func locationChanged(notification: NSNotification?) {
    guard let data = notification?.userInfo?["data"] as? YourData else {return}
}

然后从您的位置控制器发布内容:

let userInfo = ["data": mydata] 
NSNotificationCenter.defaultCenter().postNotificationName("locationChanged", object: nil, userInfo: info)