这是我正在使用的一个非常基本的支出...
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
@IBOutlet weak var mapView: MKMapView!
// Call the locationManager class
let LocationManager = CLLocationManager()
// CoreData Delegate
let appDelegate = UIApplication.shared.delegate as! AppDelegate
override func viewDidLoad() {
super.viewDidLoad()
// Conform to Delegate Method
self.LocationManager.delegate = self
// Set required accuracy
self.LocationManager.desiredAccuracy = kCLLocationAccuracyBest
// Blue dot
self.mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// check location services active
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
// check location services
switch CLLocationManager.authorizationStatus() {
case .authorizedAlways:
self.LocationManager.startUpdatingLocation()
case .notDetermined:
self.LocationManager.requestAlwaysAuthorization()
case .authorizedWhenInUse, .restricted, .denied:
let alertController = UIAlertController(
title: "Background Location Access Disabled",
message: "In order to work your location settings need to be set to 'Always'.",
preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
let openAction = UIAlertAction(title: "Open Settings", style: .default) { (action) in
if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
UIApplication.shared.open(url as URL)
}
}
alertController.addAction(openAction)
self.present(alertController, animated: true, completion: nil)
}
}
// Location delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
// get last location
let location = locations.last
print(location!.coordinate.latitude)
// set region
let region = MKCoordinateRegion(center: location!.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
// deploy region to map
self.mapView.setRegion(region, animated: true)
// Map to follow the user
self.mapView.setUserTrackingMode(MKUserTrackingMode.follow, animated: true)
// Show compass on map
self.mapView.showsCompass = true
// save the location data to CoreData
//self.save(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
// end Location updating
self.LocationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Errors: " + error.localizedDescription)
}
}
我的问题是func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]
一次又一次地调用自己(初始加载时大约3次)......
我使用的是.last
,其中AFAIK用于取出该对象中的最后一个结果..它可能就是这样,因为断点在前两次打印后插入它只会返回1个结果... < / p>
经过高低搜索,我希望通过提问来得到结果......谢谢!
答案 0 :(得分:1)
当您致电startUpdatingLocation()
时,位置管理员会立即开始提供位置数据。第一个收到的位置可能偏离您的实际位置,因此请检查horizontalAccuracy
和verticalAccuracy
属性,并关闭过于不准确的位置。
答案 1 :(得分:0)
看起来您只想获得一次性位置,如果是这样,请尝试以下代码:
// Use:
// at class level:
// var manager: LocationOneShotManager?
// in viewDidLoad:
// manager = LocationOneShotManager()
// manager!.fetchWithCompletion {location, error in
// // fetch location or an error
// if let loc = location {
// println(location)
// } else if let err = error {
// println(err.localizedDescription)
// }
// self.manager = nil
// }
import UIKit
import CoreLocation
// possible errors
enum OneShotLocationManagerErrors: Int {
case AuthorizationDenied
case AuthorizationNotDetermined
case InvalidLocation
}
class LocationOneShotManager: NSObject, CLLocationManagerDelegate {
// location manager
private var locationManager: CLLocationManager?
// destroy the manager
deinit {
locationManager?.delegate = nil
locationManager = nil
}
typealias LocationClosure = ((location: CLLocation?, error: NSError?)->())
private var didComplete: LocationClosure?
// location manager returned, call didcomplete closure
private func _didComplete(location: CLLocation?, error: NSError?) {
locationManager?.stopUpdatingLocation()
didComplete?(location: location, error: error)
locationManager?.delegate = nil
locationManager = nil
}
// location authorization status changed
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .AuthorizedWhenInUse:
self.locationManager!.startUpdatingLocation()
case .Denied:
_didComplete(nil, error: NSError(domain: self.classForCoder.description(),
code: OneShotLocationManagerErrors.AuthorizationDenied.rawValue,
userInfo: nil))
default:
break
}
}
internal func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
_didComplete(nil, error: error)
}
internal func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
_didComplete(location, error: nil)
}
// ask for location permissions, fetch 1 location, and return
func fetchWithCompletion(completion: LocationClosure) {
// store the completion closure
didComplete = completion
// fire the location manager
locationManager = CLLocationManager()
locationManager!.delegate = self
// check for description key and ask permissions
if (NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationWhenInUseUsageDescription") != nil) {
locationManager!.requestWhenInUseAuthorization()
} else if (NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationAlwaysUsageDescription") != nil) {
locationManager!.requestAlwaysAuthorization()
} else {
fatalError("To use location in iOS8 you need to define either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in the app bundle's Info.plist file")
}
}
}