Implementar métodos CLLocationManagerDelegate em Swift
-
21-12-2019 - |
Pergunta
Estou tentando fazer isso funcionar há algum tempo e vim aqui para perguntar: como faço para usar os métodos CLLocationManagerDelegate em Swift?Coloquei isso no topo da minha classe:
var locationManager = CLLocationManager()
Eu coloquei o seguinte no meu viewDidLoad
método:
locationManager.delegate = self
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
E tentei usar esses métodos delegados sem sucesso:
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {
locationReceived = true
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationReceived = false
}
Também tentei usar @optional na frente das funções, mas o Xcode gerou um erro do compilador.Alguma ideia?
Solução
Você precisa adicionar o NSLocationAlwaysUsageDescription
ou NSLocationWhenInUseUsageDescription
chave para o seu plist, se ainda não o fez, agora eles são obrigatórios,
iOS8+ requer que uma dessas duas strings seja configurada para usar locais.Qual você usa depende de como você pretende solicitar a localização.
Usar
NSLocationAlwaysUsageDescription
para aplicativos que desejam usar a localização do dispositivo mesmo quando o aplicativo não está aberto e em uso.Usar
NSLocationWhenInUseUsageDescription
para aplicativos que desejam usar a localização do dispositivo somente quando o aplicativo estiver aberto e em uso.
Observação: Ao adicionar as strings, antes de compilar e executar, exclua o aplicativo do seu dispositivo e deixe-o fazer uma nova instalação.Parece que se o aplicativo foi autorizado a usar locais antes de você atualizar para o iOS8, ele não pede sua permissão novamente e não vê que você definiu essas strings.Fazer uma exclusão e instalação limpa resolve isso.
Definir qualquer uma das strings exibe um pop-up na instalação/primeiro uso nos moldes de:"Permitir que "ThisApp" acesse sua localização mesmo quando você não estiver usando o aplicativo"
Aqui está um Captura de tela do lista arquivo.
Outras dicas
Primeiro adicione estas duas linhas no arquivo plist
1) NSLocationWhenInUseUsageDescription
2) NSLocationAlwaysUsageDescription
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
}
func initLocationManager() {
seenError = false
locationFixAchieved = false
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.locationServicesEnabled
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
}
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)
}
}
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)")
}
}
Para obter a localização atual do usuário: -
Passo 1: let locationManager = CLLocationManager() // make object of CLLocationManager class.
Passo 2: In viewDidLoad instantiate the CLLocationManager class like,
//Para uso em segundo plano
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if (CLLocationManager.locationServicesEnabled())
{
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
Etapa 3: Agora implemente os métodos delegados de CLLocationManager
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var locValue:CLLocationCoordinate2D = manager.location.coordinate
println("locations = \(locValue.latitude) \(locValue.longitude)")
}
Passo 4:Não se esqueça de adicionar NSLocationAlwaysUsageDescription
no Info.plist como no iOS 8 é obrigatório adicionar isto.Isso pedirá permissão para usar a localização do usuário.
Eu tive o mesmo problema.didUpdateLocations - não estava funcionando.Execute seu aplicativo.Vá para a página Configurações -> Privacidade -> Localização e desative os Serviços de Localização.didFailWithError detectará o erro sobre a ausência dos Serviços de Localização.Em seguida, ligue-o.Desde aquele momento, didUpdateLocations irá capturar locais.
Este é um tópico um pouco antigo, mas nenhuma das opções acima funcionou para mim no Swift 2.2 xCode 7.3.1.
O problema é que eu estava usando:
func locationManager(manager: CLLocationManager!, didUpdateLocation locations: [AnyObject]!) {
print("Got location")
locationManager.stopUpdatingLocation()
}
E isso nunca foi chamado.Quando mudei para:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Got location")
locationManager.stopUpdatingLocation()
}
Tudo deu certo.Parece que o delegado não é chamado ao usar [AnyObject]