iOS CLLocationManager在一个单独的类

我有多个视图控制器需要获取用户的位置,所以我想创build一个单独的类,ViewControllers可以调用获取用户的最新位置。

locationManager:didUpdateToLocation:fromLocation返回void。 一旦用户的经度和纬度被计算出来,我怎样才能将纬度和经度数据传回给我的ViewControllers?

我可以尝试在我的locationManaging类中写入getter和setter,但是如果我这样做,我怎么知道何时从我的ViewController类调用纬度getter和longitude getter方法? 如何让ViewController的主线程等待locationManaging类的纬度和经度值?

谢谢!

创build一个具有latitudelongitude属性的singleton类, startLocatingendLocating 。 在类中,创build一个CLLocationManager实例,并将其委托设置为单例。 在startLocatingendLocating ,调用CLLocationManager实例的相应方法。 使委托方法更新latitudelongitude属性。 在其他ViewControllers ,阅读这个单例的latitudelongitude属性。

要知道何时从另一个ViewController读取这些属性,请在这些属性上设置一个观察者(请参阅NSKeyValueObserving Protocol Reference

在做这件事之前,查找互联网的现有代码。

这样做后,上传到GitHub许可证。

正如user1071136所说,一个单身的位置pipe理器可能是你想要的。 创build一个类,NSObject的一个子类,只有一个属性, CLLocationManager

LocationManagerSingleton.h:

 #import <MapKit/MapKit.h> @interface LocationManagerSingleton : NSObject <CLLocationManagerDelegate> @property (nonatomic, strong) CLLocationManager* locationManager; + (LocationManagerSingleton*)sharedSingleton; @end 

LocationManagerSingleton.m:

 #import "LocationManagerSingleton.h" @implementation LocationManagerSingleton @synthesize locationManager; - (id)init { self = [super init]; if(self) { self.locationManager = [CLLocationManager new]; [self.locationManager setDelegate:self]; [self.locationManager setDistanceFilter:kCLDistanceFilterNone]; [self.locationManager setHeadingFilter:kCLHeadingFilterNone]; [self.locationManager startUpdatingLocation]; //do any more customization to your location manager } return self; } + (LocationManagerSingleton*)sharedSingleton { static LocationManagerSingleton* sharedSingleton; if(!sharedSingleton) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedSingleton = [LocationManagerSingleton new]; } } return sharedSingleton; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { //handle your location updates here } - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { //handle your heading updates here- I would suggest only handling the nth update, because they //come in fast and furious and it takes a lot of processing power to handle all of them } @end 

要获取最近收到的位置,只需使用[LocationManagerSingleton sharedSingleton].locationManager.location 。 可能需要几秒钟的时间来预热GPS以获得准确的位置。

基于上述的答案,这里是我所做的,你可以find完整的例子在github https://github.com/irfanlone/CLLocationManager-Singleton-Swift

只需在项目中导入此文件,然后您可以select实施LocationUpdateProtocol或侦听位置更新的通知

 import MapKit protocol LocationUpdateProtocol { func locationDidUpdateToLocation(location : CLLocation) } /// Notification on update of location. UserInfo contains CLLocation for key "location" let kLocationDidChangeNotification = "LocationDidChangeNotification" class UserLocationManager: NSObject, CLLocationManagerDelegate { static let SharedManager = UserLocationManager() private var locationManager = CLLocationManager() var currentLocation : CLLocation? var delegate : LocationUpdateProtocol! private override init () { super.init() self.locationManager.delegate = self self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.distanceFilter = kCLLocationAccuracyHundredMeters locationManager.requestAlwaysAuthorization() self.locationManager.startUpdatingLocation() } // MARK: - CLLocationManagerDelegate func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) { currentLocation = newLocation let userInfo : NSDictionary = ["location" : currentLocation!] dispatch_async(dispatch_get_main_queue()) { () -> Void in self.delegate.locationDidUpdateToLocation(self.currentLocation!) NSNotificationCenter.defaultCenter().postNotificationName(kLocationDidChangeNotification, object: self, userInfo: userInfo as [NSObject : AnyObject]) } } } 

用法:

 class ViewController: UIViewController, LocationUpdateProtocol { var currentLocation : CLLocation! override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "locationUpdateNotification:", name: kLocationDidChangeNotification, object: nil) let LocationMgr = UserLocationManager.SharedManager LocationMgr.delegate = self } // MARK: - Notifications func locationUpdateNotification(notification: NSNotification) { let userinfo = notification.userInfo self.currentLocation = userinfo!["location"] as! CLLocation print("Latitude : \(self.currentLocation.coordinate.latitude)") print("Longitude : \(self.currentLocation.coordinate.longitude)") } // MARK: - LocationUpdateProtocol func locationDidUpdateToLocation(location: CLLocation) { currentLocation = location print("Latitude : \(self.currentLocation.coordinate.latitude)") print("Longitude : \(self.currentLocation.coordinate.longitude)") } } 

这就是我在快速实施位置pipe理器singleton时所做的。 这是基于user1071136的战略,以及这种快速的模式 。

 // // UserLocationManager.swift // // Use: call SharedUserLocation.currentLocation2d from any class import MapKit class UserLocation: NSObject, CLLocationManagerDelegate { var locationManager = CLLocationManager() // You can access the lat and long by calling: // currentLocation2d.latitude, etc var currentLocation2d:CLLocationCoordinate2D? class var manager: UserLocation { return SharedUserLocation } init () { super.init() if self.locationManager.respondsToSelector(Selector("requestAlwaysAuthorization")) { self.locationManager.requestWhenInUseAuthorization() } self.locationManager.delegate = self self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.distanceFilter = 50 self.locationManager.startUpdatingLocation() } func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { self.currentLocation2d = manager.location.coordinate } } let SharedUserLocation = UserLocation() 

在学习获取单身类的用户位置的过程中,我下载了这个代码https://github.com/irfanlone/CLLocationManager-Singleton-Swift 。 在Xcode8.3.3 Swift 3上运行后,我无法在debugging控制台中获得任何输出。 实际上,我甚至无法得到这个位置authenticationdlalog显示。 我怀疑来自单身人士的数据没有传递给视图控制器,但我不能罚款的解决scheme,你能看到什么是错的? 谢谢。

Swift 3的更正后的代码是:// Singleton:import MapKit

协议LocationUpdateProtocol {func locationDidUpdateToLocation(_ location:CLLocation)}

让kLocationDidChangeNotification =“LocationDidChangeNotification”

类UserLocationManager:NSObject,CLLocationManagerDelegate {

 static let SharedManager = UserLocationManager() fileprivate var locationManager = CLLocationManager() var currentLocation : CLLocation? var delegate : LocationUpdateProtocol! fileprivate override init () { super.init() self.locationManager.delegate = self self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.distanceFilter = kCLLocationAccuracyHundredMeters locationManager.requestAlwaysAuthorization() self.locationManager.startUpdatingLocation() } // MARK: - CLLocationManagerDelegate func locationManager(manager: CLLocationManager,didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) { currentLocation = newLocation let userInfo : NSDictionary = ["location" : currentLocation!] DispatchQueue.main.async() { () -> Void in self.delegate.locationDidUpdateToLocation(self.currentLocation!) NotificationCenter.default.post(name: Notification.Name(kLocationDidChangeNotification), object: self, userInfo: userInfo as [NSObject : AnyObject]) } } 

}

// ViewController导入UIKit导入CoreLocation

class ViewController:UIViewController,LocationUpdateProtocol {

 var currentLocation : CLLocation! override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(ViewController.locationUpdateNotification(_:)), name: NSNotification.Name(rawValue: kLocationDidChangeNotification), object: nil) let LocationMgr = UserLocationManager.SharedManager LocationMgr.delegate = self } // MARK: - Notifications func locationUpdateNotification(_ notification: Notification) { let userinfo = notification.userInfo self.currentLocation = userinfo!["location"] as! CLLocation print("Latitude : \(self.currentLocation.coordinate.latitude)") print("Longitude : \(self.currentLocation.coordinate.longitude)") } // MARK: - LocationUpdateProtocol func locationDidUpdateToLocation(_ location: CLLocation) { currentLocation = location print("Latitude : \(self.currentLocation.coordinate.latitude)") print("Longitude : \(self.currentLocation.coordinate.longitude)") } 

}