作为练习,我试图将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中正常工作
您缺少两件事。首先,您必须使用requestAlwaysAuthorization
或requestWhenInUseAuthorization()
寻求许可。因此,您的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。
如果您希望默认情况下更新用户位置,而不必每次都单击“模拟位置”,请转到
这将请求许可并跟踪是否已授予许可,否则会发出警报退出。在按下后退按钮时停止跟踪。
Swift:
只需调用init(vc:UIViewController)。
首先将这两行添加到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)")
}
}
}
[我不确定为什么,但是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起已过时,因此快速桥接层显然根本不支持该格式。
有相同的问题。 didUpdateLocations-无法正常工作。运行您的应用。转到“设置”页面->隐私->位置,然后关闭位置服务。 didFailWithError将捕获有关缺少位置服务的错误。然后打开它。从那一刻起,didUpdateLocations将捕获位置。
我希望有两种方法。
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扩展方法,它使标签文本以绿色/红色打开/关闭。
这是我非常简单的代码,可以正常工作:
首先在通用/链接框架和库中添加核心位置框架
然后将以下内容添加到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)")
}
}
对于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)")
}
}
不要忘记添加NSLocationWhenInUseUsesDescription或NSLocationAlwaysUsageDescription在您的配置文件中(目标/信息/自定义iOS目标属性)>
在info.plist