我有需要获取用户的位置的多个视图控制器,所以我想创建一个单独的类的ViewControllers可以调用来获取用户的最新位置。
的LocationManager:didUpdateToLocation:fromLocation返回void。 我如何尽快通过经纬度数据回到我ViewControllers作为用户的经度和纬度计算?
我可以尝试在我locationManaging类写getter和setter方法,但如果我这样做,我怎么知道何时调用从我的ViewController类纬度getter和经度getter方法? 我如何保存视图控制器的主线程等待来自locationManaging类的纬度和经度值?
谢谢!
Answer 1:
创建具有一个单独的类latitude
和longitude
特性, startLocating
和endLocating
。 在类中,创建一个CLLocationManager
实例,并设置其代表是单身。 在startLocating
和endLocating
,调用适当的方法CLLocationManager
实例。 使委托方法更新latitude
和longitude
属性。 在其他ViewControllers
,请阅读此单的latitude
和longitude
属性。
要知道什么时候读出其它的那些属性ViewController
,这些属性设置观察者(见NSKeyValueObserving协议参考
在此之前,查找现有代码的因特网和。
这样做了以后,把它上传到GitHub上用一个许可证。
Answer 2:
作为user1071136说,单身位置管理器可能是你想要的东西。 创建一个类,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才能得到准确的位置。
Answer 3:
基于以上的答案,这里是我做的,你可以在github完整的例子https://github.com/irfanlone/CLLocationManager-Singleton-Swift
只需导入此文件在您的项目,那么你可以选择实施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)")
}
}
Answer 4:
下面是我在实现迅速的位置马槽单身时一样。 它是基于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()
Answer 5:
在学习中的一个单独的类以获得用户位置的过程中,我下载了这个代码https://github.com/irfanlone/CLLocationManager-Singleton-Swift 。 它foddleing使在运行上Xcode8.3.3斯威夫特3之后,我无法在调试控制台中的任何输出。 事实上,我甚至不能得到这个位置autherization dlalog显示。 我怀疑从单数据没有传递到视图控制器,但我不能罚款解决方案,你可以看到什么是错的? 谢谢。
对于夫特3校正后的代码是:
//The singleton:
import MapKit
protocol LocationUpdateProtocol {
func locationDidUpdateToLocation(_ location : CLLocation)
}
let kLocationDidChangeNotification = "LocationDidChangeNotification"
class 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])
}
}
}
// The ViewController
import UIKit
import 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)")
}
}
文章来源: iOS CLLocationManager in a separate class