Менеджер CLLocation в Swift, чтобы получить местоположение пользователя

Я пытаюсь преобразовать старое приложение в 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" } } 

Любая помощь или указатели на то, где искать, будут оценены. Благодарю.

EDIT: Обновлено из предложений, но все еще не работает

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 как указано здесь .

Сначала добавьте две строки в файл plist

1) NSLocationWhenInUseUsageDescription

2) NSLocationAlwaysUsageDescription

Тогда это classная работа, полная реализация этого

 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 Extenion, который делает текст метки вкл. / Выкл. Зеленым / красным цветом.

Вот мой очень простой код, который работает:

сначала добавьте структуру основного местоположения в общие / связанные структуры и библиотеки

затем добавьте следующее в Info.plist:

 NSLocationWhenInUseUsageDescription blablabla NSLocationAlwaysUsageDescription blablabla 

это мой файл 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)") } } 

не забудьте добавить NSLocationWhenInUseUsageDescription или NSLocationAlwaysUsageDescription в свой файл конфигурации (целевые / Info / пользовательские целевые свойства iOS

Добавьте следующее свойство 2 в info.plist

 NSLocationWhenInUseUsageDescription : Location information is used for fraud prevention Privacy - Location Usage Description : Location information is used for fraud prevention 

Если вы хотите, чтобы местоположение пользователя обновлялось по умолчанию, без щелчка «Имитировать местоположение» каждый раз, перейдите к

 YourProject-->Build Phases-->Link Binary with libraries-->Add corelocation.framework 

Местоположение автоматически обновляется / по умолчанию при запуске приложения в симуляторе. Протестировано и работает в Swift 2!

Это потребует разрешения и отслеживания, если при наличии другого разрешения выйдет предупреждение. Остановка отслеживания нажатием кнопки «Назад».

info.plist

 NSLocationAlwaysUsageDescription Allow tracking while completing a survey 

Класс:

 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) }) } } 
  • Как добавить панель инструментов над клавиатурой?
  • Swift readonly external, внутреннее свойство readwrite
  • Что является хорошим примером для различения fileprivate и private в Swift3
  • iOS 7 - Как отобразить выбор даты в виде таблицы?
  • Как hash NSString с SHA1 в Swift?
  • Swift Array дополнительно Тип и подписка (бета-версия 3)
  • Как инициализировать структуру из объекта json
  • Быстрые расширения протоколов
  • Как получить текущее время как время
  • Заголовок Swift для Objective-C, не созданный в Xcode 6
  • Прочитайте файл / URL-адрес по строке в Swift
  • Давайте будем гением компьютера.