Swift中的CLLocation Manager获取用户的位置
我正在尝试将ObjC中的旧应用程序转换为Swift作为练习练习,并遇到了一些问题。 我在老应用程序中使用它的方式是build立CLLocation Manager,然后使用:
manager = [[CLLocationManager alloc]init]; manager.delegate = self; manager.desiredAccuracy = kCLLocationAccuracyBest; [manager startUpdatingLocation]
这将自动调用:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ }
从那里我可以提取所有我需要的信息。 但是迅速,这种方法没有自动完成,我不知道如何重现它。 文件说这个
startUpdatingLocation()
仍然会被代表调用,但是并没有发生。
这是我迄今为止:
import UIKit import corelocation class ViewController: UIViewController,CLLocationManagerDelegate{ @IBOutlet var gpsResult : UILabel var manager:CLLocationManager! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. manager = CLLocationManager() manager.delegate = self manager.desiredAccuracy = kCLLocationAccuracyBest manager.startUpdatingLocation() } func locationManager(manager:CLLocationManager, didUpdateLocations locations:AnyObject[]) { println("locations = \(locations)") gpsResult.text = "success" } }
任何帮助或指针在哪里看,将不胜感激。 谢谢。
编辑:从build议更新,但仍然无法正常工作
编辑2:似乎是不允许该方法在ViewController中正常工作的一些错误
你错过了两件事。 首先,您必须使用requestAlwaysAuthorization
或requestWhenInUseAuthorization()
来请求权限。 所以你的viewDidLoad()
应该是这样的:
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. locationManager = CLLocationManager() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() locationManager.startUpdatingLocation() }
其次, 按照此处所示编辑您的Info.plist
。
首先在plist文件中添加这两行
1)NSLocationWhenInUseUsageDescription
2)NSLocationAlwaysUsageDescription
然后这是class级工作完成的工具
import UIKit import CoreLocation @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate { var window: UIWindow? var locationManager: CLLocationManager! var seenError : Bool = false var locationFixAchieved : Bool = false var locationStatus : NSString = "Not Started" func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { initLocationManager(); return true } // Location Manager helper stuff func initLocationManager() { seenError = false locationFixAchieved = false locationManager = CLLocationManager() locationManager.delegate = self locationManager.locationServicesEnabled locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() } // Location Manager Delegate stuff // If failed func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) { locationManager.stopUpdatingLocation() if (error) { if (seenError == false) { seenError = true print(error) } } } func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) { if (locationFixAchieved == false) { locationFixAchieved = true var locationArray = locations as NSArray var locationObj = locationArray.lastObject as CLLocation var coord = locationObj.coordinate println(coord.latitude) println(coord.longitude) } } // authorization status func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) { var shouldIAllow = false switch status { case CLAuthorizationStatus.Restricted: locationStatus = "Restricted Access to location" case CLAuthorizationStatus.Denied: locationStatus = "User denied access to location" case CLAuthorizationStatus.NotDetermined: locationStatus = "Status not determined" default: locationStatus = "Allowed to location Access" shouldIAllow = true } NSNotificationCenter.defaultCenter().postNotificationName("LabelHasbeenUpdated", object: nil) if (shouldIAllow == true) { NSLog("Location to Allowed") // Start location services locationManager.startUpdatingLocation() } else { NSLog("Denied access: \(locationStatus)") } } }
我不知道为什么,但似乎startUpdatingLocation
没有在iOS 7模拟器上呈现用户提示,但是当我手动启用它时,如果我使用委托方法的较新forms,它会像预期的那样工作:
var manager:CLLocationManager! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. manager = CLLocationManager() manager.delegate = self manager.desiredAccuracy = kCLLocationAccuracyBest manager.startUpdatingLocation() } func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) { // Updated to current array syntax [AnyObject] rather than AnyObject[] println("locations = \(locations)") }
你使用的格式已经被弃用,因为iOS 5或者6版本,所以显然它不受快速桥接层的支持。
有同样的问题。 didUpdateLocations – 没有工作。 运行你的应用程序 转到设置页面 – >隐私 – >位置,并closures位置服务。 didFailWithError将捕获关于缺less定位服务的错误。 然后打开它。 从那一刻起,UpdateUpocations将捕获位置。
这是我的非常简单的代码:
首先在General / Linked Frameworks和Libraries中添加Core Location框架
然后添加到Info.plist中:
<key>NSLocationWhenInUseUsageDescription</key> <string>blablabla</string> <key>NSLocationAlwaysUsageDescription</key> <string>blablabla</string>
这是我的ViewController.swift文件:
import UIKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate { var locationManager:CLLocationManager! override func viewDidLoad() { super.viewDidLoad() locationManager = CLLocationManager() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() locationManager.startUpdatingLocation() } func locationManager(manager:CLLocationManager, didUpdateLocations locations: [CLLocation]) { print("locations = \(locations)") } }
不要忘了添加NSLocationWhenInUseUsageDescription或NSLocationAlwaysUsageDescription在你的configuration文件(target / Info / custom iOS target properties
在info.plist中添加下面两个属性
NSLocationWhenInUseUsageDescription : Location information is used for fraud prevention Privacy - Location Usage Description : Location information is used for fraud prevention
我希望有两种方法。
var locationManager: CLLocationManager = CLLocationManager() var initialLocation :CLLocation? var updatedUserLocation :CLLocation? override func viewDidLoad() { super.viewDidLoad() { //MapView Location locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.requestWhenInUseAuthorization() locationManager.startUpdatingLocation() locationManager.startUpdatingHeading() }
实现CLLocationManagerDelegate:
//CLLocationManager Delegate func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // This only works when user location is updated. gpsProviderStatusLabel.changeStatusToOn(gpsProviderStatusLabel) } func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { //Error indicates GPS permission restricted gpsProviderStatusLabel.changeStatusToOff(gpsProviderStatusLabel) //Initial Location initialLocation = locations.first //Getting Updated Location updatedUserLocation = locations.last }
检查CLLocationDelegate授权:
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { //This method does real time status monitoring. switch status { case .NotDetermined: print(".NotDetermined") break case .AuthorizedAlways: print(".AuthorizedAlways") gpsProviderStatusLabel.changeStatusToOn(gpsProviderStatusLabel) break case .Denied: print(".Denied") gpsProviderStatusLabel.changeStatusToOff(gpsProviderStatusLabel) break case .AuthorizedWhenInUse: print(".AuthorizedWhenInUse") gpsProviderStatusLabel.changeStatusToOn(gpsProviderStatusLabel) break case .Restricted: print(".Restricted") break default: print("Unhandled authorization status") break } }
注意:changeStatusToOn或changeStatusToOff是一个UILabel Extenion方法,它使标签文本开/关与绿色/红色的颜色。
如果您想要默认更新用户位置,而无需每次点击“模拟位置”,请转到
YourProject-->Build Phases-->Link Binary with libraries-->Add corelocation.framework
在模拟器中运行应用程序时,位置会自动更新/默认情况下。 testing并在Swift 2中工作!
这将要求权限和跟踪,如果给予权限,或者退出警报。 停止跟踪后退button按下。
info.plist中
<key>NSLocationAlwaysUsageDescription</key> <string>Allow tracking while completing a survey</string>
类:
import UIKit import CoreLocation class LocationViewController: BaseViewController, CLLocationManagerDelegate { // MARK: Constants private static let enableLocationServices = [ "title" : "Location", "message" : "Enable location services", "buttonTitle" : "OK" ] // MARK: Private variables private var manager: CLLocationManager? // MARK: UIViewCOntroller methods @IBAction func backButtonPressed(sender : UIButton) { stopTracking() detatchLocationManager() dismissViewControllerAnimated(true, completion: nil) } override func viewDidLoad() { super.viewDidLoad() attachLocationManager() } // Mark: Location func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { if status == .AuthorizedAlways { manager.startUpdatingLocation() } else if status != .NotDetermined { showEnableLocationServicesAlert() } } func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { for location in locations { getDependencyService().getProject().appendLocationTrackingFile(location.timestamp, latitude: location.coordinate.latitude, longitude: location.coordinate.longitude) } } // MARK: LocationViewController private func attachLocationManager() { manager = CLLocationManager() manager?.delegate = self manager?.desiredAccuracy = kCLLocationAccuracyBest if CLLocationManager.authorizationStatus() != .AuthorizedAlways { manager?.requestAlwaysAuthorization() } else if CLLocationManager.locationServicesEnabled() { startTracking() } } private func detatchLocationManager() { manager?.stopUpdatingLocation() manager?.delegate = nil manager = nil } private func startTracking() { manager?.startUpdatingLocation() } private func stopTracking() { manager?.stopUpdatingLocation() } private func showEnableLocationServicesAlert() { getDependencyService().getUiHelper().showAlert(FrogFirstSurveyViewController.enableLocationServices, completion: { self.dismissViewControllerAnimated(true, completion: nil) }) } }
对于Swift 3
import UIKit import CoreLocation class ViewController: UIViewController,CLLocationManagerDelegate { var locationManager:CLLocationManager! override func viewDidLoad() { super.viewDidLoad() locationManager = CLLocationManager() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() locationManager.startUpdatingLocation() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func locationManager(_ manager:CLLocationManager, didUpdateLocations locations: [CLLocation]) { print("locations = \(locations)") } }