Swift中的CLLocation Manager以获取用户的位置

问题描述 投票:28回答:13

作为练习,我试图将ObjC中的旧应用程序转换为Swift,并遇到了一些问题。我在旧应用程序中使用它的方式是建立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"
}
}

任何帮助或指向何处的指针都将不胜感激。谢谢。

编辑:从建议中更新,但仍无法正常工作

EDIT2:似乎是一些错误,导致该方法无法在ViewController中正常工作

cllocationmanager swift
13个回答
64
投票

您缺少两件事。首先,您必须使用requestAlwaysAuthorizationrequestWhenInUseAuthorization()寻求许可。因此,您的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 as indicated here


0
投票

如果您希望默认情况下更新用户位置,而不必每次都单击“模拟位置”,请转到


0
投票

这将请求许可并跟踪是否已授予许可,否则会发出警报退出。在按下后退按钮时停止跟踪。


0
投票

Swift:


0
投票

只需调用init(vc:UIViewController)。


22
投票

首先将这两行添加到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
// 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)")
        }
}
}

6
投票

[我不确定为什么,但是startUpdatingLocation似乎没有在iOS 7模拟器上显示用户提示,但是当我手动启用它时,如果使用较新形式的委托方法,它将按预期工作:

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起已过时,因此快速桥接层显然根本不支持该格式。


3
投票

有相同的问题。 didUpdateLocations-无法正常工作。运行您的应用。转到“设置”页面->隐私->位置,然后关闭位置服务。 didFailWithError将捕获有关缺少位置服务的错误。然后打开它。从那一刻起,didUpdateLocations将捕获位置。


2
投票

我希望有两种方法。

    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扩展方法,它使标签文本以绿色/红色打开/关闭。


2
投票

这是我非常简单的代码,可以正常工作:

首先在通用/链接框架和库中添加核心位置框架

然后将以下内容添加到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)")
    }

}

2
投票

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


}

1
投票

不要忘记添加NSLocationWhenInUseUsesDescription或NSLocationAlwaysUsageDescription在您的配置文件中(目标/信息/自定义iOS目标属性)>


0
投票

info.plist

© www.soinside.com 2019 - 2024. All rights reserved.