如何在Swift中使用CLLocationManager获取用户位置?

14

我在我的视图控制器上有这段代码,但它没有起作用:

  import UIKit
  import CoreLocation

  class ViewController: UIViewController, CLLocationManagerDelegate {

   var location: CLLocationManager!

  override func viewDidLoad() {
     super.viewDidLoad()

     location=CLLocationManager()
     location.delegate = self
     location.desiredAccuracy=kCLLocationAccuracyBest
     location.startUpdatingLocation()
 }

  func locationManager(location:CLLocationManager, didUpdateLocations locations:AnyObject[]) {
     println("locations = \(locations)")
     label1.text = "success"
 }

我已经按照其他帖子中的说明设置了权限,但我从来没有得到过任何输出或打印信息。

谢谢!


这对我有效。 这是一个简单的例子,请参见:https://dev59.com/pI_ea4cB1Zd3GeqPPYQP#35973586 - Leandro Parice
7个回答

19

首先,在plist文件中添加以下两行:

1)NSLocationWhenInUseUsageDescription

2)NSLocationAlwaysUsageDescription

然后,实现这个类的工作就完成了。

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

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

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

1
你好。我按照你写的做了一切,但是CLAuthorizationStatus.status始终是NotDetermined。为什么? - Farhad
6
"locationServicesEnabled" 不可用:自iOS 7及更早版本弃用的API在Swift中不可用。 - Leon
  • 以未捕获的NSException类型终止。如何修复?
- Leon
1
@jayeshkavathiya 为什么需要将代码放在AppDelegate类中? - zbz.lvlv
@tim - 请将那一行替换为以下代码:CLLocationManager.locationServicesEnabled() - Andrew
显示剩余3条评论

5
以下是在Swift 3中获取用户位置的简单步骤:
1)首先,在plist文件中添加以下行及其描述:
 NSLocationWhenInUseUsageDescription

2) 在您的项目中添加CoreLocation.framework(在“Build Phases->Link Binary With Library”部分下)

3) 在AppDelegate类中

   import CoreLocation

4) 创建locationManager对象如下:

    var locationManager:CLLocationManager!

5) 在didFinishLaunchingWithOptions中编写以下代码

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = 200
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()

6) 确认 CLLocationManagerDelegate 代理如下:

   class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate

7) 编写CLLocationManagerDelegate委托方法以获取用户位置

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

    print("location error is = \(error.localizedDescription)")

}


func locationManager(_ manager: CLLocationManager,
                     didUpdateLocations locations: [CLLocation]) {

    let locValue:CLLocationCoordinate2D = (manager.location?.coordinate)!


    print("Current Locations = \(locValue.latitude) \(locValue.longitude)")
}

2

这段代码与上面的代码相同,但已经进行了清理以适用于Swift语言,截至本文发布日期,此代码对我有效。

向原作者致敬。

(注意:将其放入您将用来处理位置信息的任何类中。)

var lastLocation = CLLocation()
var locationAuthorizationStatus:CLAuthorizationStatus!
var window: UIWindow?
var locationManager: CLLocationManager!
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    
    
    self.initLocationManager()
    
}
    // Location Manager helper stuff
    func initLocationManager() {
        seenError = false
        locationFixAchieved = false
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        
        locationManager.requestAlwaysAuthorization()
    }
    
    // Location Manager Delegate stuff
    
    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
        locationManager.stopUpdatingLocation()
        if ((error) != nil) {
            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)
        }
    }
    
    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)")
            }
    }


如何获取用户旧位置 @Wade? - Muruganandham K
我不确定你所说的“旧位置”是什么意思。你是指你上次所在的位置吗? - Christopher Wade Cantley
  • (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
以上方法是Objective C中的。我需要与上述方法具有相同参数的精确替换。
- Muruganandham K

2

由于您将位置声明为明确展开的可选项 (CLLocationManager!),因此它需要一个初始化器,可以在init方法中如jhurray建议的那样,在内联中进行初始化,如下所示:

var location: CLLocationManager! = nil

请注意,您可能还会遇到其他问题,包括iOS 8对查询用户是否允许使用CoreLocation的权限有新的要求。请参阅此问题以获取更多信息。

我有权限,但我不知道是否全部都有。但是我可以通过断点查看,发现该函数没有被调用:func locationManager(location:CLLocationManager, didUpdateLocations locations:AnyObject[]) { println("locations = (locations)") label1.text = "success" }为什么我的应用程序不使用这个函数呢? - user3745888
请检查其他链接并确保您都调用了“requestWhenInUseAuthorization / requestAlwaysAuthorization”并在Info.plist中设置了正确的键。另外,请检查您是否进行了正确的调用以启动管理器。 - David Berry

1

在视图控制器中执行以下操作 [使用 Swift] -

  class ViewController:     
  UIViewController,MKMapViewDelegate,CLLocationManagerDelegate {


  var locationManager: CLLocationManager?
  var usersCurrentLocation:CLLocationCoordinate2D?

  override func viewDidLoad() {
    super.viewDidLoad()

    self.locationManager = CLLocationManager()

    if CLLocationManager.authorizationStatus() == .NotDetermined{
        locationManager?.requestAlwaysAuthorization()
    }

    locationManager?.desiredAccuracy = kCLLocationAccuracyBest
    locationManager?.distanceFilter = 200
    locationManager?.delegate = self
    startUpdatingLocation()

    usersCurrentLocation = CLLocationCoordinate2DMake(LATTITUDE, LONGITUDE)
    let span = MKCoordinateSpanMake(0.005, 0.005)
    let region = MKCoordinateRegionMake(usersCurrentLocation!, span)
    mapview.setRegion(region, animated: true)
    mapview.delegate = self
    mapview.showsUserLocation = true

}

//MARK: CLLocationManagerDelegate方法

(这段文字是关于CLLocationManagerDelegate的方法,保留了HTML格式,不进行解释)
func startUpdatingLocation() {
    self.locationManager?.startUpdatingLocation()
}

func stopUpdatingLocation() {
    self.locationManager?.stopUpdatingLocation()
}

// MARK: MKMapViewDelegate

func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation){
    mapview.centerCoordinate = userLocation.location!.coordinate
    mapview.showsUserLocation = true
    regionWithGeofencing()

}

0

应该写成

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {


0

你需要有init函数。

重写init(coder:)和init(nibName: bundle:),并添加任何自定义的init。

因为你已经说过位置不是可选项,在所有的init函数中调用super init之前必须初始化它。

func init() {
...
location = CLLocationManager()
// either set delegate and other stuff here or in viewDidLoad
super.init(nibName:nil, bundle:nil)
// other initialization below

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接