在Swift中实现CLLocationManagerDelegate方法

27

我一直在尝试让这个工作起来,现在我来询问一下-如何在Swift中使用CLLocationManagerDelegate方法?我已经把这个放在类的顶部:

var locationManager = CLLocationManager()

我已将以下内容放入我的viewDidLoad方法中:

locationManager.delegate = self
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()

我已经尝试使用这些委托方法,但都没有成功:

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {
    locationReceived = true
}

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    locationReceived = false
}

我曾尝试在函数前面使用@optional,但Xcode会抛出编译器错误。有什么想法吗?


我也尝试过在函数前面使用@optional,但是这会导致Xcode报错。有什么解决方法吗?

你的代码在我的设备上似乎可以运行,你是否收到了询问应用程序是否可以使用你的位置的对话框? - voidref
@voidref 既然你提到了,我没有收到对话框。这有点奇怪...我刚刚检查了设置,应用程序也被授予了位置访问权限。 - user1327904
5个回答

58
如果您还没有这样做,需要在您的plist中添加NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription键,它们现在是强制性的。请注意,不要删除任何HTML标签。
iOS8+需要设置以下两个字符串之一才能使用位置信息。使用哪一个取决于您如何请求位置信息。
- 对于希望在应用程序未打开或使用时也使用设备位置的应用程序,请使用“NSLocationAlwaysUsageDescription”。 - 对于仅想在应用程序打开并使用时使用设备位置的应用程序,请使用“NSLocationWhenInUseUsageDescription”。
注意:在添加字符串之前,构建和运行之前,请从设备中删除应用程序,并进行全新安装。如果应用程序在升级到iOS8之前已获得了使用位置信息的授权,则不会再次请求您的许可,并且不会看到您设置的这些字符串。删除并进行全新安装可以解决此问题。
设置任意一个字符串都会提示一个弹出窗口,类似于:“即使您未使用该应用程序,是否允许“ThisApp”访问您的位置信息”
下面是一个plist文件的截图。

enter image description here


你的意思是像这样吗?(http://imgur.com/5CA1tKK)?但这也没有使对话框出现。 - user1327904
1
不,显然iOS8需要设置另外两个字符串之一(请参见我的编辑)。根据我的理解,您使用哪一个取决于您打算如何请求位置,但我找不到更具体的信息。为了全面披露,即使在添加所示的字符串后,我的仍未能正常工作(我的问题似乎在其他地方,在此时我正在尝试不使用swift运行我的),我只是想提到这些字符串,因为现在它们是必需的。 - Wesley Smith
2
请将以下内容添加到info.plist文件中:<key>NSLocationUsageDescription</key> <string>您的信息</string> <key>NSLocationAlwaysUsageDescription</key> <string>您的信息</string> <key>NSLocationWhenInUsageDescription</key> <string>您的信息</string> - avalla
3
info.plist的关键字包括:NSLocationAlwaysUsageDescription和NSLocationWhenInUseUsageDescription。正确拼写这些关键字非常重要,这在CLLocationManager文档中有所记录,可搜索此文本进行查询。在我更正了这些关键字后,我的应用程序可以正常工作,并在调用过程中请求权限。 - David Wilson
@DavidWilson 哦,是的,我错过了NSLocationWhenInUseUsageDescription中的“使用”,谢谢! - Wesley Smith
显示剩余2条评论

7

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

1) NSLocationWhenInUseUsageDescription

2) NSLocationAlwaysUsageDescription


(注:这是关于iOS应用程序的权限设置,需要在info.plist文件中添加相应的描述信息)
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate

var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"

var locationManager: CLLocationManager!

override func viewDidLoad() {
    super.viewDidLoad()
}

  func initLocationManager() {
   seenError = false
   locationFixAchieved = false
    locationManager = CLLocationManager()
   locationManager.delegate = self
   locationManager.locationServicesEnabled
   locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
}

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

5

获取用户当前位置:

步骤1:let locationManager = CLLocationManager() // 创建CLLocationManager类的对象。

步骤2:在viewDidLoad中实例化CLLocationManager类,如下所示:

// 用于后台使用

self.locationManager.requestAlwaysAuthorization()

// For use in foreground

self.locationManager.requestWhenInUseAuthorization()

if (CLLocationManager.locationServicesEnabled())
{
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}

步骤 3:现在实现CLLocationManager的委托方法。

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

    var locValue:CLLocationCoordinate2D = manager.location.coordinate

    println("locations = \(locValue.latitude) \(locValue.longitude)")

  }

步骤 4: 不要忘记在 Info.plist 中添加 NSLocationAlwaysUsageDescription,因为在 iOS 8 中这是强制性的。这将请求使用用户位置的权限。


3

我遇到了同样的问题。didUpdateLocations - 没有正常工作。运行您的应用程序。 前往设置页面 -> 隐私 -> 位置,关闭位置服务。didFailWithError将捕获有关缺失位置服务的错误。然后再打开它。从那时起,didUpdateLocations将捕获到位置。


这似乎是有效的,但当我从Xcode重新启动应用程序后,我又回到了无法获取任何位置更新的状态。 - FractalDoctor
1
是的,我知道。但我猜这可能是XCode 6的问题。让我们等待beta 2 :) - salty

0

这是一个有点老的帖子,但以上方法都无法在Swift 2.2 xCode 7.3.1上为我工作。

问题是我正在使用:

func locationManager(manager: CLLocationManager!, didUpdateLocation locations: [AnyObject]!) {
    print("Got location")
    locationManager.stopUpdatingLocation()
}

而这个从未被调用。当我改成:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    print("Got location")
    locationManager.stopUpdatingLocation()
}

一切都解决了。似乎在使用 [AnyObject] 时,委托不会被调用。


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