Get User's Current Location / Coordinates
如何存储用户的当前位置并在地图上显示位置?
我能够在地图上显示预定义的坐标,我只是不知道如何从设备接收信息。
另外我知道我必须在Plist中添加一些项目。 我怎样才能做到这一点?
要获取用户的当前位置,您需要声明:
1 | let locationManager = CLLocationManager() |
在
1 2 3 4 5 6 7 8 9 10 11 | // Ask for Authorisation from the User. self.locationManager.requestAlwaysAuthorization() // For use in foreground self.locationManager.requestWhenInUseAuthorization() if CLLocationManager.locationServicesEnabled() { locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.startUpdatingLocation() } |
然后在CLLocationManagerDelegate方法中,您可以获取用户的当前位置坐标:
1 2 3 4 | func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return } print("locations = \(locValue.latitude) \(locValue.longitude)") } |
在info.plist中,您必须添加
和您的自定义警报消息; AppName(演示应用)想要使用您当前的位置。
你应该做这些步骤:
初始位置管理员:
1 2 3 4 5 | locationManager = CLLocationManager() locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() locationManager.startUpdatingLocation() |
获取用户位置:
1 2 3 4 | func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let locValue:CLLocationCoordinate2D = manager.location!.coordinate print("locations = \(locValue.latitude) \(locValue.longitude)") } |
使用Swift 5更新iOS 12.2
you must add following privacy permissions in plist file
1 2 3 4 5 6 7 8 | <key>NSLocationWhenInUseUsageDescription</key> <string>Description</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>Description</string> <key>NSLocationAlwaysUsageDescription</key> <string>Description</string> |
我就是这样
getting current location and showing on Map in Swift 2.0
确保已将CoreLocation和MapKit框架添加到项目中(XCode 7.2.1不需要这样做)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import Foundation import CoreLocation import MapKit class DiscoverViewController : UIViewController, CLLocationManagerDelegate { @IBOutlet weak var map: MKMapView! var locationManager: CLLocationManager! override func viewDidLoad() { super.viewDidLoad() if (CLLocationManager.locationServicesEnabled()) { locationManager = CLLocationManager() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() locationManager.startUpdatingLocation() } } func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last! as CLLocation let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude) let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)) self.map.setRegion(region, animated: true) } } |
这是结果屏幕
NSLocationWhenInUseUsageDescription =在应用程序处于后台时请求使用位置服务的权限。在你的plist文件中。
如果这样有效,那么请投票给答案。
导入库如:
1 | import CoreLocation |
设置代表:
1 | CLLocationManagerDelegate |
变量如下:
1 | var locationManager:CLLocationManager! |
在viewDidLoad()上写这个漂亮的代码:
1 2 3 4 5 6 7 8 | locationManager = CLLocationManager() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() if CLLocationManager.locationServicesEnabled(){ locationManager.startUpdatingLocation() } |
编写CLLocation委托方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | //MARK: - location delegate methods func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let userLocation :CLLocation = locations[0] as CLLocation print("user latitude = \(userLocation.coordinate.latitude)") print("user longitude = \(userLocation.coordinate.longitude)") self.labelLat.text ="\(userLocation.coordinate.latitude)" self.labelLongi.text ="\(userLocation.coordinate.longitude)" let geocoder = CLGeocoder() geocoder.reverseGeocodeLocation(userLocation) { (placemarks, error) in if (error != nil){ print("error in reverseGeocode") } let placemark = placemarks! as [CLPlacemark] if placemark.count>0{ let placemark = placemarks![0] print(placemark.locality!) print(placemark.administrativeArea!) print(placemark.country!) self.labelAdd.text ="\(placemark.locality!), \(placemark.administrativeArea!), \(placemark.country!)" } } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Error \(error)") } |
现在设置访问该位置的权限,因此将这些键值添加到info.plist文件中
1 2 3 4 5 6 | <key>NSLocationAlwaysUsageDescription</key> <string>Will you allow this app to always know your location?</string> <key>NSLocationWhenInUseUsageDescription</key> <string>Do you allow this app to know your current location?</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>Do you allow this app to know your current location?</string> |
100%正常工作没有任何问题。 TESTED
首先导入Corelocation和MapKit库:
1 2 | import MapKit import CoreLocation |
从CLLocationManagerDelegate继承到我们的类
1 | class ViewController: UIViewController, CLLocationManagerDelegate |
创建一个locationManager变量,这将是您的位置数据
1 | var locationManager = CLLocationManager() |
创建一个函数来获取位置信息,具体这个确切的语法有效:
1 | func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { |
在您的函数中为用户创建一个常量当前位置
1 | let userLocation:CLLocation = locations[0] as CLLocation // note that locations is same as the one in the function declaration |
停止更新位置,这可以防止您的设备在移动时不断更改窗口以使您的位置居中(如果您希望它以其他方式运行,您可以省略它)
1 | manager.stopUpdatingLocation() |
从刚刚定义的userLocatin获取用户坐标:
1 | let coordinations = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude,longitude: userLocation.coordinate.longitude) |
定义你想要你的地图缩放的方式:
结合这两个来获得区域:
1 | let region = MKCoordinateRegion(center: coordinations, span: span)//this basically tells your map where to look and where from what distance |
现在设置区域并选择是否要使用动画去那里
1 | mapView.setRegion(region, animated: true) |
关闭你的功能
从您的按钮或您想要将locationManagerDeleget设置为self的其他方式
现在允许显示位置
指定准确性
1 | locationManager.desiredAccuracy = kCLLocationAccuracyBest |
授权:
1 | locationManager.requestWhenInUseAuthorization() |
为了能够授权位置服务,您需要将这两行添加到您的plist
获取位置:
1 | locationManager.startUpdatingLocation() |
向用户显示:
1 | mapView.showsUserLocation = true |
这是我的完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import UIKit import MapKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate { @IBOutlet weak var mapView: MKMapView! var locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() // 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. } @IBAction func locateMe(sender: UIBarButtonItem) { locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestWhenInUseAuthorization() locationManager.startUpdatingLocation() mapView.showsUserLocation = true } func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let userLocation:CLLocation = locations[0] as CLLocation manager.stopUpdatingLocation() let coordinations = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude,longitude: userLocation.coordinate.longitude) let span = MKCoordinateSpanMake(0.2,0.2) let region = MKCoordinateRegion(center: coordinations, span: span) mapView.setRegion(region, animated: true) } } |
Swift 3.0
如果您不想在地图中显示用户位置,但只想将其存储在firebase或其他地方,请按照以下步骤操作:
1 2 | import MapKit import CoreLocation |
现在在VC上使用CLLocationManagerDelegate,您必须覆盖下面显示的最后三个方法。您可以看到requestLocation()方法如何使用这些方法获取当前用户位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | class MyVc: UIViewController, CLLocationManagerDelegate { let locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() isAuthorizedtoGetUserLocation() if CLLocationManager.locationServicesEnabled() { locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters } } //if we have no permission to access user location, then ask user for permission. func isAuthorizedtoGetUserLocation() { if CLLocationManager.authorizationStatus() != .authorizedWhenInUse { locationManager.requestWhenInUseAuthorization() } } //this method will be called each time when a user change his location access preference. func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { if status == .authorizedWhenInUse { print("User allowed us to access location") //do whatever init activities here. } } //this method is called by the framework on locationManager.requestLocation(); func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { print("Did location updates is called") //store the user location here to firebase or somewhere } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Did location updates is called but failed getting location \(error)") } } |
现在,您可以在用户登录您的应用后对以下电话进行编码。调用requestLocation()时,它将进一步调用上面的didUpdateLocations,您可以将该位置存储到Firebase或其他任何位置。
1 2 3 | if CLLocationManager.locationServicesEnabled() { locationManager.requestLocation(); } |
如果您使用的是GeoFire,那么在上面的didUpdateLocations方法中,您可以按如下方式存储位置
1 | geoFire?.setLocation(locations.first, forKey: uid) where uid is the user id who logged in to the app. I think you will know how to get UID based on your app sign in implementation. |
最后但并非最不重要的,请转到您的Info.plist并启用"隐私 - 使用时的位置使用说明"。
当您使用模拟器进行测试时,它总是为您提供一个在Simulator - > Debug - > Location中配置的自定义位置。
首先在项目中添加两个框架
1:MapKit
2:Corelocation(从XCode 7.2.1开始不再需要)
在课堂上定义
1 2 | var manager:CLLocationManager! var myLocations: [CLLocation] = [] |
然后在viewDidLoad方法代码中这样做
1 2 3 4 5 6 7 | manager = CLLocationManager() manager.desiredAccuracy = kCLLocationAccuracyBest manager.requestAlwaysAuthorization() manager.startUpdatingLocation() //Setup our Map View mapobj.showsUserLocation = true |
不要忘记在plist文件中添加这两个值
1 2 3 | 1: NSLocationWhenInUseUsageDescription 2: NSLocationAlwaysUsageDescription |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import CoreLocation import UIKit class ViewController: UIViewController, CLLocationManagerDelegate { var locationManager: CLLocationManager! override func viewDidLoad() { super.viewDidLoad() locationManager = CLLocationManager() locationManager.delegate = self locationManager.requestWhenInUseAuthorization() } func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { if status != .authorizedWhenInUse {return} locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.startUpdatingLocation() let locValue: CLLocationCoordinate2D = manager.location!.coordinate print("locations = \(locValue.latitude) \(locValue.longitude)") } } |
由于对
1 2 3 4 5 6 7 8 9 10 11 12 13 | override func viewDidLoad() { super.viewDidLoad() locationManager.requestWhenInUseAuthorization(); if CLLocationManager.locationServicesEnabled() { locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.startUpdatingLocation() } else{ print("Location service disabled"); } } |
这是你的视图做的加载方法,并且在ViewController类中还包括mapStart更新方法,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { var locValue : CLLocationCoordinate2D = manager.location.coordinate; let span2 = MKCoordinateSpanMake(1, 1) let long = locValue.longitude; let lat = locValue.latitude; print(long); print(lat); let loadlocation = CLLocationCoordinate2D( latitude: lat, longitude: long ) mapView.centerCoordinate = loadlocation; locationManager.stopUpdatingLocation(); } |
另外,不要忘记在项目中添加CoreLocation.FrameWork和MapKit.Framework(从XCode 7.2.1开始不再需要)
用法:
在课堂上定义字段
1 | let getLocation = GetLocation() |
通过简单的代码在类的功能中使用:
1 2 3 4 5 6 7 | getLocation.run { if let location = $0 { print("location = \(location.coordinate.latitude) \(location.coordinate.longitude)") } else { print("Get Location failed \(getLocation.didFailWithError)") } } |
类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import CoreLocation public class GetLocation: NSObject, CLLocationManagerDelegate { let manager = CLLocationManager() var locationCallback: ((CLLocation?) -> Void)! var locationServicesEnabled = false var didFailWithError: Error? public func run(callback: @escaping (CLLocation?) -> Void) { locationCallback = callback manager.delegate = self manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation manager.requestWhenInUseAuthorization() locationServicesEnabled = CLLocationManager.locationServicesEnabled() if locationServicesEnabled { manager.startUpdatingLocation() } else { locationCallback(nil) } } public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { locationCallback(locations.last!) manager.stopUpdatingLocation() } public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { didFailWithError = error locationCallback(nil) manager.stopUpdatingLocation() } deinit { manager.stopUpdatingLocation() } } |
这是一个适合我的复制粘贴示例。
http://swiftdeveloperblog.com/code-examples/determine-users-current-location-example-in-swift/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | import UIKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate { var locationManager:CLLocationManager! override func viewDidLoad() { super.viewDidLoad() // 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. } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) determineMyCurrentLocation() } func determineMyCurrentLocation() { locationManager = CLLocationManager() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() if CLLocationManager.locationServicesEnabled() { locationManager.startUpdatingLocation() //locationManager.startUpdatingHeading() } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let userLocation:CLLocation = locations[0] as CLLocation // Call stopUpdatingLocation() to stop listening for location updates, // other wise this function will be called every time when user location changes. // manager.stopUpdatingLocation() print("user latitude = \(userLocation.coordinate.latitude)") print("user longitude = \(userLocation.coordinate.longitude)") } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Error \(error)") } } |
100%在iOS Swift 4中工作:Parmar Sajjad
第1步:转到GoogleDeveloper Api控制台并创建您的ApiKey
第2步:转到项目安装Cocoapods GoogleMaps pod
第3步:转到AppDelegate.swift导入GoogleMaps和
1 2 3 4 5 6 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. GMSServices.provideAPIKey("ApiKey") return true } |
第4步:
导入UIKit
导入GoogleMaps
class ViewController:UIViewController,CLLocationManagerDelegate {
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | @IBOutlet weak var mapview: UIView! let locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() locationManagerSetting() // 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 locationManagerSetting() { self.locationManager.delegate = self self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters self.locationManager.requestWhenInUseAuthorization() self.locationManager.startUpdatingLocation() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { self.showCurrentLocationonMap() self.locationManager.stopUpdatingLocation() } func showCurrentLocationonMap() { let cameraposition = GMSCameraPosition.camera(withLatitude: (self.locationManager.location?.coordinate.latitude)! , longitude: (self.locationManager.location?.coordinate.longitude)!, zoom: 18) let mapviewposition = GMSMapView.map(withFrame: CGRect(x: 0, y: 0, width: self.mapview.frame.size.width, height: self.mapview.frame.size.height), camera: cameraposition) mapviewposition.settings.myLocationButton = true mapviewposition.isMyLocationEnabled = true let marker = GMSMarker() marker.position = cameraposition.target marker.snippet ="Macczeb Technologies" marker.appearAnimation = GMSMarkerAnimation.pop marker.map = mapviewposition self.mapview.addSubview(mapviewposition) } |
}
步骤5:打开info.plist文件并在下面添加隐私 - 使用时的位置用法说明......在主故事板文件基本名称下面
第六步:跑
1 2 3 4 5 6 7 8 | // its with strongboard @IBOutlet weak var mapView: MKMapView! //12.9767415,77.6903967 - exact location latitude n longitude location let cooridinate = CLLocationCoordinate2D(latitude: 12.9767415 , longitude: 77.6903967) let spanDegree = MKCoordinateSpan(latitudeDelta: 0.2,longitudeDelta: 0.2) let region = MKCoordinateRegion(center: cooridinate , span: spanDegree) mapView.setRegion(region, animated: true) |