获取用户的当前位置/坐标

Awa*_*ain 179 iphone location cllocationmanager ios swift

如何存储用户的当前位置并在地图上显示位置?

我能够在地图上显示预定义的坐标,我只是不知道如何从设备接收信息.

另外我知道我必须在Plist中添加一些项目.我怎样才能做到这一点?

Ann*_*nnu 211

要获取用户的当前位置,您需要声明:

let locationManager = CLLocationManager()
Run Code Online (Sandbox Code Playgroud)

viewDidLoad()你必须实例化CLLocationManager类,如下所示:

// 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()
}
Run Code Online (Sandbox Code Playgroud)

然后在CLLocationManagerDelegate方法中,您可以获取用户的当前位置坐标:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
    print("locations = \(locValue.latitude) \(locValue.longitude)")
}
Run Code Online (Sandbox Code Playgroud)

在info.plist中,您必须添加NSLocationAlwaysUsageDescription 和您的自定义警报消息; AppName(演示应用)想要使用您当前的位置.

  • 不要忘记`导入MapKit` +`CoreLocation` +在类定义中添加`CLLocationManagerDelegate`. (54认同)
  • `NSLocationAlwaysUsageDescription`已重命名为`Privacy - Location Always Usage Description` (11认同)
  • @Yusha如果你看起来像Objective-C那么你从未见过Objective-C(也不是Swift) (6认同)
  • 您忘了提及CLLocationManagerDelegate协议的实现. (4认同)
  • 你必须在`viewDidLoad`中将`locationManager`声明为全局变量而不是局部变量 (4认同)
  • 也不要忘记在你得到它后`stopUpdatingLocation()`。 (2认同)

itz*_*har 99

你应该做这些步骤:

  1. 添加CoreLocation.framework到BuildPhases - >使用库链接二进制文件(从XCode 7.2.1开始不再需要)
  2. 导入CoreLocation到您的类 - 很可能是ViewController.swift
  3. 添加CLLocationManagerDelegate到您的类声明中
  4. 添加NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription到PList
  5. 初始位置管理员:

    locationManager = CLLocationManager()
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    locationManager.startUpdatingLocation()
    
    Run Code Online (Sandbox Code Playgroud)
  6. 获取用户位置:

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let locValue:CLLocationCoordinate2D = manager.location!.coordinate
        print("locations = \(locValue.latitude) \(locValue.longitude)")
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 新函数:func locationManager(manager:CLLocationManager,didUpdateLocations locations:[CLLocation]) (3认同)

swi*_*Boy 46

我就是这样

获取当前位置并在Swift 2.0中显示在Map上

确保已将CoreLocationMapKit框架添加到项目中(XCode 7.2.1 不需要这样做)

<key>NSLocationWhenInUseUsageDescription</key>
<string>Description</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Description</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>Description</string>
Run Code Online (Sandbox Code Playgroud)

这是结果屏幕

该地图的屏幕截图,以孟买为中心


Ann*_*nnu 29

@wonderwhy我添加了我的代码截图. 请检查一下. 您必须在plist中添加<code> NSLocationWhenInUseUsageDescription以进行授权.</ code>

NSLocationWhenInUseUsageDescription =在应用程序处于后台时请求使用位置服务的权限.在你的plist文件中.

如果这样有效,那么请投票给答案.

  • 使用标记语言而不是粘贴屏幕截图来获取代码片段会很不错 (12认同)

Mr.*_*ani 26

导入库如:

import CoreLocation
Run Code Online (Sandbox Code Playgroud)

设置代表:

CLLocationManagerDelegate
Run Code Online (Sandbox Code Playgroud)

变量如下:

var locationManager:CLLocationManager!
Run Code Online (Sandbox Code Playgroud)

在viewDidLoad()上写这个漂亮的代码:

 locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()

    if CLLocationManager.locationServicesEnabled(){
        locationManager.startUpdatingLocation()
    }
Run Code Online (Sandbox Code Playgroud)

编写CLLocation委托方法:

    //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)")
}
Run Code Online (Sandbox Code Playgroud)

现在设置访问该位置的权限,因此将这些键值添加到info.plist文件中

 <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>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

100%正常工作没有任何问题.TESTED


Mil*_*iuM 25

首先导入Corelocation和MapKit库:

import MapKit
import CoreLocation
Run Code Online (Sandbox Code Playgroud)

从CLLocationManagerDelegate继承到我们的类

class ViewController: UIViewController, CLLocationManagerDelegate
Run Code Online (Sandbox Code Playgroud)

创建一个locationManager变量,这将是您的位置数据

var locationManager = CLLocationManager()
Run Code Online (Sandbox Code Playgroud)

创建一个函数来获取位置信息,具体这个确切的语法有效:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
Run Code Online (Sandbox Code Playgroud)

在您的函数中为用户创建一个常量当前位置

let userLocation:CLLocation = locations[0] as CLLocation // note that locations is same as the one in the function declaration  
Run Code Online (Sandbox Code Playgroud)

停止更新位置,这可以防止您的设备在移动时不断更改窗口以使您的位置居中(如果您希望它以其他方式运行,您可以省略它)

manager.stopUpdatingLocation()
Run Code Online (Sandbox Code Playgroud)

从刚刚定义的userLocatin获取用户坐标:

let coordinations = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude,longitude: userLocation.coordinate.longitude)
Run Code Online (Sandbox Code Playgroud)

定义你想要你的地图缩放的方式:

let span = MKCoordinateSpanMake(0.2,0.2) 结合这两个来获得区域:

let region = MKCoordinateRegion(center: coordinations, span: span)//this basically tells your map where to look and where from what distance
Run Code Online (Sandbox Code Playgroud)

现在设置区域并选择是否要使用动画去那里

mapView.setRegion(region, animated: true)
Run Code Online (Sandbox Code Playgroud)

关闭你的功能 }

从您的按钮或您想要将locationManagerDeleget设置为self的其他方式

现在允许显示位置

指定准确性

locationManager.desiredAccuracy = kCLLocationAccuracyBest
Run Code Online (Sandbox Code Playgroud)

授权:

 locationManager.requestWhenInUseAuthorization()
Run Code Online (Sandbox Code Playgroud)

为了能够授权位置服务,您需要将这两行添加到您的plist

在此输入图像描述

获取位置:

locationManager.startUpdatingLocation()
Run Code Online (Sandbox Code Playgroud)

向用户显示:

mapView.showsUserLocation = true
Run Code Online (Sandbox Code Playgroud)

这是我的完整代码:

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)

    }
}
Run Code Online (Sandbox Code Playgroud)


Lyj*_*son 20

Swift 3.0

如果您不想在地图中显示用户位置,但只想将其存储在firebase或其他地方,请按照以下步骤操作:

import MapKit
import CoreLocation
Run Code Online (Sandbox Code Playgroud)

现在在VC上使用CLLocationManagerDelegate,您必须覆盖下面显示的最后三个方法.您可以看到requestLocation()方法如何使用这些方法获取当前用户位置.

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)")
}

}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在用户登录您的应用后对以下电话进行编码.调用requestLocation()时,它将进一步调用上面的didUpdateLocations,您可以将该位置存储到Firebase或其他任何位置.

if CLLocationManager.locationServicesEnabled() {
            locationManager.requestLocation();
 }
Run Code Online (Sandbox Code Playgroud)

如果您使用的是GeoFire,那么在上面的didUpdateLocations方法中,您可以按如下方式存储位置

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. 
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的,请转到您的Info.plist并启用"隐私 - 使用时的位置使用说明".

当您使用模拟器进行测试时,它总是为您提供一个在Simulator - > Debug - > Location中配置的自定义位置.


Kru*_*tel 15

首先在项目中添加两个框架

1:MapKit

2:Corelocation(从XCode 7.2.1开始不再需要)

在课堂上定义

var manager:CLLocationManager!
var myLocations: [CLLocation] = []
Run Code Online (Sandbox Code Playgroud)

然后在viewDidLoad方法代码中这样做

manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()

//Setup our Map View
mapobj.showsUserLocation = true
Run Code Online (Sandbox Code Playgroud)

不要忘记在plist文件中添加这两个值

1: NSLocationWhenInUseUsageDescription

2: NSLocationAlwaysUsageDescription
Run Code Online (Sandbox Code Playgroud)


Ren*_*tik 13

用法:

在类中定义字段

let getLocation = GetLocation()
Run Code Online (Sandbox Code Playgroud)

通过简单的代码在类的函数中使用:

getLocation.run {
    if let location = $0 {
        print("location = \(location.coordinate.latitude) \(location.coordinate.longitude)")
    } else {
        print("Get Location failed \(getLocation.didFailWithError)")
    }
}
Run Code Online (Sandbox Code Playgroud)

班级:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)


不要忘记在 info.plist 中添加“NSLocationWhenInUseUsageDescription”。

  • 谢谢!不要忘记在 info.plist 中添加“NSLocationWhenInUseUsageDescription” (2认同)

Tek*_*Raj 10

 override func viewDidLoad() {

    super.viewDidLoad()       
    locationManager.requestWhenInUseAuthorization();     
    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
        locationManager.startUpdatingLocation()
    }
    else{
        print("Location service disabled");
    }
  }
Run Code Online (Sandbox Code Playgroud)

这是你的视图做的加载方法,并且在ViewController类中还包括mapStart更新方法,如下所示

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();
}
Run Code Online (Sandbox Code Playgroud)

另外,不要忘记在项目中添加CoreLocation.FrameWork和MapKit.Framework(从XCode 7.2.1开始不再需要)


Sco*_*des 10

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)")
    }
}
Run Code Online (Sandbox Code Playgroud)

由于调用requestWhenInUseAuthorization是异步的,因此应用程序locationManager在用户授予权限或拒绝权限后调用该函数.因此,在用户授予权限的情况下,将您的位置置于该函数内是正确的. 这是我在其上发现的最好的教程.


Man*_*mam 5

import Foundation
import CoreLocation

enum Result<T> {
  case success(T)
  case failure(Error)
}

final class LocationService: NSObject {
    private let manager: CLLocationManager

    init(manager: CLLocationManager = .init()) {
        self.manager = manager
        super.init()
        manager.delegate = self
    }

    var newLocation: ((Result<CLLocation>) -> Void)?
    var didChangeStatus: ((Bool) -> Void)?

    var status: CLAuthorizationStatus {
        return CLLocationManager.authorizationStatus()
    }

    func requestLocationAuthorization() {
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.requestWhenInUseAuthorization()
        if CLLocationManager.locationServicesEnabled() {
            manager.startUpdatingLocation()
            //locationManager.startUpdatingHeading()
        }
    }

    func getLocation() {
        manager.requestLocation()
    }

    deinit {
        manager.stopUpdatingLocation()
    }

}

 extension LocationService: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        newLocation?(.failure(error))
        manager.stopUpdatingLocation()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.sorted(by: {$0.timestamp > $1.timestamp}).first {
            newLocation?(.success(location))
        }
        manager.stopUpdatingLocation()
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .notDetermined, .restricted, .denied:
            didChangeStatus?(false)
        default:
            didChangeStatus?(true)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

需要在所需的 ViewController 中编写此代码。

 //NOTE:: Add permission in info.plist::: NSLocationWhenInUseUsageDescription


let locationService = LocationService()

 @IBAction func action_AllowButtonTapped(_ sender: Any) {
     didTapAllow()
 }

 func didTapAllow() {
     locationService.requestLocationAuthorization()
 }

 func getCurrentLocationCoordinates(){
   locationService.newLocation = {result in
     switch result {
      case .success(let location):
      print(location.coordinate.latitude, location.coordinate.longitude)
      case .failure(let error):
      assertionFailure("Error getting the users location \(error)")
   }
  }
}

func getCurrentLocationCoordinates() {
    locationService.newLocation = { result in
        switch result {
        case .success(let location):
            print(location.coordinate.latitude, location.coordinate.longitude)
            CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
                if error != nil {
                    print("Reverse geocoder failed with error" + (error?.localizedDescription)!)
                    return
                }
                if (placemarks?.count)! > 0 {
                    print("placemarks", placemarks!)
                    let pmark = placemarks?[0]
                    self.displayLocationInfo(pmark)
                } else {
                    print("Problem with the data received from geocoder")
                }
            })
        case .failure(let error):
            assertionFailure("Error getting the users location \(error)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)