Swift 中的 CLLocation 管理器获取用户的位置
Posted
技术标签:
【中文标题】Swift 中的 CLLocation 管理器获取用户的位置【英文标题】:CLLocation Manager in Swift to get Location of User 【发布时间】:2014-07-26 15:49:38 【问题描述】:我正在尝试将 ObjC 中的旧应用程序转换为 Swift 作为练习,但遇到了一些问题。我在旧应用程序中使用它的方式是建立 CLLocation 管理器,然后我会使用:
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 中正常工作
【问题讨论】:
你可以在这里看到完整的答案:***.com/a/31277543/3166417 edit 2 还有效吗?既然你接受了答案.. 【参考方案1】:你错过了两件事。首先,您必须使用requestAlwaysAuthorization
或requestWhenInUseAuthorization()
请求许可。所以你的viewDidLoad()
应该是这样的:
var locationManager = CLLocationManager()
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
其次,编辑你的Info.plist
as indicated here。
【讨论】:
确保 info.plist 中有 ios 8 的有效行,这是我的问题【参考方案2】:首先在plist文件中添加这两行
NSLocationWhenInUseUsageDescription
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)")
【讨论】:
你能告诉我如何在我的 Controller.swift 中使用上述内容吗? 您可以在任何地方使用,只需在您的 viewcontroler 中而不是 appdelegate 中编写此代码。这不会有任何不同。只需从 viewdidload() 调用 InitLocationManager() 其他一切都会一样... 我试过了,但对我不起作用,我发布了一个关于它的问题here。 这就是我的答案。更多信息developer.apple.com/library/ios/documentation/General/Reference/… 此代码有效,但只是第一次,一旦用户接受请求,locationManager.startUpdatingLocation() 就不会在后续应用程序运行中再次调用。【参考方案3】:我不知道为什么,但似乎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 以来已被弃用,因此显然 swift 桥接层根本不支持它。
【讨论】:
对不起,在这种情况下,“手动启用”是什么意思? @大卫 @SeanFitz 进入设置>隐私>位置并确保您的应用已启用。 @SeanFitz 如果您在设备上使用它,只要您不尝试使用已弃用的方法,它似乎就可以正常工作。 我在我的设备上构建了代码,正如您在上面看到的,使用您向我展示的新方法,但 locationManager() 从未从 manager.startUpdatingLocation 调用。它只是完全没有任何作用。 @大卫 @SeanFitz 在现场设备上还是在模拟器上?进入设置>隐私>位置并确保您的应用程序已启用。【参考方案4】:有同样的问题。 didUpdateLocations - 没有工作。运行您的应用程序。转到设置页面 -> 隐私 -> 位置并关闭定位服务。 didFailWithError 将捕获有关缺少位置服务的错误。然后打开它。从那一刻起,didUpdateLocations 将捕获位置。
【讨论】:
【参考方案5】:这是我非常简单的代码:
首先在 General/Linked Frameworks and Libraries 中添加 Core Location 框架
然后将以下内容添加到 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)")
【讨论】:
【参考方案6】:对于 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)")
【讨论】:
【参考方案7】:我希望有两种方法。
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 扩展方法,它使标签文本以绿色/红色颜色打开/关闭。
【讨论】:
【参考方案8】:别忘了添加 NSLocationWhenInUseUsageDescription 或 NSLocationAlwaysUsageDescription 在您的配置文件中(目标/信息/自定义 iOS 目标属性
【讨论】:
【参考方案9】:在 info.plist
中添加 bellow 2 属性NSLocationWhenInUseUsageDescription : Location information is used for fraud prevention
Privacy - Location Usage Description : Location information is used for fraud prevention
【讨论】:
【参考方案10】:如果您想默认更新用户位置,而不是每次都点击“模拟位置”,请转到
YourProject-->Build Phases-->Link Binary with libraries-->Add corelocation.framework
当您在模拟器中运行应用程序时,位置会自动/默认更新。在 Swift 2 中测试并运行!
【讨论】:
我只是关注并添加了 corelocation.framework,但它对我不起作用。 不确定它是否是 XCode 特定版本的功能,但我正在使用它来跟踪用户的默认位置,用于天气应用【参考方案11】:这将请求许可并跟踪是否获得许可,否则退出并发出警报。按下后退按钮时停止跟踪。
info.plist
<key>NSLocationAlwaysUsageDescription</key>
<string>Allow tracking while completing a survey</string>
类:
import UIKit
import CoreLocation
class LocationViewController: BaseViewController, CLLocationManagerDelegate
// MARK: Constants
private static let enableLocationServices = [
"title" : "Location",
"message" : "Enable location services",
"buttonTitle" : "OK"
]
// MARK: Private variables
private var manager: CLLocationManager?
// MARK: UIViewCOntroller methods
@IBAction func backButtonPressed(sender : UIButton)
stopTracking()
detatchLocationManager()
dismissViewControllerAnimated(true, completion: nil)
override func viewDidLoad()
super.viewDidLoad()
attachLocationManager()
// Mark: Location
func locationManager(manager: CLLocationManager,
didChangeAuthorizationStatus status: CLAuthorizationStatus)
if status == .AuthorizedAlways
manager.startUpdatingLocation()
else if status != .NotDetermined
showEnableLocationServicesAlert()
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
for location in locations
getDependencyService().getProject().appendLocationTrackingFile(location.timestamp, latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
// MARK: LocationViewController
private func attachLocationManager()
manager = CLLocationManager()
manager?.delegate = self
manager?.desiredAccuracy = kCLLocationAccuracyBest
if CLLocationManager.authorizationStatus() != .AuthorizedAlways
manager?.requestAlwaysAuthorization()
else if CLLocationManager.locationServicesEnabled()
startTracking()
private func detatchLocationManager()
manager?.stopUpdatingLocation()
manager?.delegate = nil
manager = nil
private func startTracking()
manager?.startUpdatingLocation()
private func stopTracking()
manager?.stopUpdatingLocation()
private func showEnableLocationServicesAlert()
getDependencyService().getUiHelper().showAlert(FrogFirstSurveyViewController.enableLocationServices, completion:
self.dismissViewControllerAnimated(true, completion: nil)
)
【讨论】:
【参考方案12】:斯威夫特:
添加以下内容
import CoreLocation
class YourViewController: UIViewController
var locationManager:CLLocationManager!
//MARK:- Location Manager
extension YourViewController: CLLocationManagerDelegate
func stratLocationManager()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.checkUsersLocationServicesAuthorization()
locationManager.startUpdatingLocation()
func checkUsersLocationServicesAuthorization()
/// Check if user has authorized Total Plus to use Location Services
if CLLocationManager.locationServicesEnabled()
switch CLLocationManager.authorizationStatus()
case .notDetermined:
// Request when-in-use authorization initially
// This is the first and the ONLY time you will be able to ask the user for permission
self.locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
break
case .restricted, .denied:
// Disable location features
PrintLogs("Location Access Not Available")
break
case .authorizedWhenInUse, .authorizedAlways:
// Enable features that require location services here.
PrintLogs("Location Access Available")
break
func locationManager(_ manager:CLLocationManager, didUpdateLocations locations: [CLLocation])
print("locations = \(locations)")
【讨论】:
【参考方案13】:只需调用 init(vc : UIViewController)。
import Foundation
import CoreLocation
import UIKit
class LocManager : NSObject
var permission : ((Bool?)->())?
private var locationManager : CLLocationManager!
init(_ vc : UIViewController)
super.init()
self.locationManager = CLLocationManager()
self.locationManager.delegate = vc as? CLLocationManagerDelegate
setUpLocationManagerDelegate()
extension LocManager : CLLocationManagerDelegate
fileprivate func setUpLocationManagerDelegate()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
if let lat = locations.last?.coordinate.latitude, let long = locations.last?.coordinate.longitude
print("\n\nThe current Lat/Long Is Here\n\n")
let coordinates = CLLocationCoordinate2D(latitude: lat, longitude: long)
else
print("Unable To Access Locaion")
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus)
switch status
case .authorizedAlways,.authorizedWhenInUse:
print("Good to go and use location")
locationManager.startUpdatingLocation()
self.callPermisssionCompletion(val: true)
case .denied:
print("DENIED to go and use location")
self.callPermisssionCompletion(val: false)
case .restricted:
print("DENIED to go and use location")
self.callPermisssionCompletion(val: nil)
case .notDetermined:
print("DENIED to go and use location")
self.callPermisssionCompletion(val: nil)
default:
print("Unable to read location :\(status)")
fileprivate func callPermisssionCompletion(val : Bool?)
guard let comp = self.permission else
print("\n\n Unable to locate completions \n\n")
return
if let val = val
comp(val)
【讨论】:
以上是关于Swift 中的 CLLocation 管理器获取用户的位置的主要内容,如果未能解决你的问题,请参考以下文章
Apple 的 CLLocation 管理器的外部 NMEA GPS
swift Swift - 扩展到CLLocation以获取坐标的笛卡尔表示。来源:http://stackoverflow.com/a/5983282/273119
swift Swift - 扩展到CLLocation以获取坐标的笛卡尔表示。来源:http://stackoverflow.com/a/5983282/273119
swift Swift - 扩展到CLLocation以获取坐标的笛卡尔表示。来源:http://stackoverflow.com/a/5983282/273119
swift Swift - 扩展到CLLocation以获取坐标的笛卡尔表示。来源:http://stackoverflow.com/a/5983282/273119