j'ai créé une classe singleton pour gérer l'autorisation de l'emplacement parce que je avais besoin pour plusieurs points de vue dans mon application. J'ai donc créé la classe Location.swift ci-dessous.alerte emplacement autorisation montrant après l'application ferme
NOTE: J'ai ajouté correctement dans Info.plist, et ai regardé plusieurs autres postes, mais aucun ne semble répondre à cette (au moins pas que je trouve)
protocol LocationServiceDelegate {
func tracingLocation(currentLocation: CLLocation)
func tracingLocationDidFailWithError(error: NSError)
}
class Location: NSObject,CLLocationManagerDelegate {
var latitude: Double!
var longitude: Double!
var currentLocation : CLLocation!
var locationManager: CLLocationManager?
var lastLocation: CLLocation?
var delegate: LocationServiceDelegate?
static let sharedInstance:Location = {
let instance = Location()
return instance
}()
override init() {
super.init()
self.locationManager = CLLocationManager()
self.locationManager?.delegate = self
guard let locationManagers = self.locationManager else {
return
}
if CLLocationManager.authorizationStatus() == .notDetermined {
locationManagers.requestWhenInUseAuthorization()
}
locationManagers.desiredAccuracy = kCLLocationAccuracyBest
locationManagers.pausesLocationUpdatesAutomatically = false
locationManagers.distanceFilter = 0.1
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else {
return
}
self.lastLocation = location
updateLocation(currentLocation: location)
}
@nonobjc func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
locationManager?.requestWhenInUseAuthorization()
break
case .authorizedWhenInUse:
locationManager?.startUpdatingLocation()
break
case .authorizedAlways:
locationManager?.startUpdatingLocation()
break
case .restricted:
// restricted by e.g. parental controls. User can't enable Location Services
break
case .denied:
// user denied your app access to Location Services, but can grant access from Settings.app
break
}
}
// Private function
private func updateLocation(currentLocation: CLLocation){
guard let delegate = self.delegate else {
return
}
delegate.tracingLocation(currentLocation: currentLocation)
}
private func updateLocationDidFailWithError(error: NSError) {
guard let delegate = self.delegate else {
return
}
delegate.tracingLocationDidFailWithError(error: error)
}
func startUpdatingLocation() {
print("Starting Location Updates")
self.locationManager?.startUpdatingLocation()
currentLocation = locationManager?.location
Location.sharedInstance.latitude = currentLocation.coordinate.latitude
Location.sharedInstance.longitude = currentLocation.coordinate.longitude
print(Location.sharedInstance.latitude, Location.sharedInstance.longitude)
// self.locationManager?.startMonitoringSignificantLocationChanges()
}
func stopUpdatingLocation() {
print("Stop Location Updates")
self.locationManager?.stopUpdatingLocation()
}
}
Mon application se bloque, et je pense C'est parce que l'autorisation de localisation n'est pas définie au début. Le plus drôle est que l'alerte de demande qui invite l'utilisateur à autoriser les services de localisation ne s'affiche pas tant que vous n'avez pas quitté l'application.
Une fois que vous fermez l'application et accepter les services de localisation, l'application fonctionne très bien. Ma question est la suivante: pourquoi l'alerte n'apparaît-elle pas?
il est également intéressant de noter que ce phénomène se produit que par un périphérique réel. Dans le simulateur, l'alerte apparaît comme prévu lorsque la vue initiale est en cours de chargement.
ma première vue qui est censé charger et les données d'exposition est la suivante:
import UIKit
import Alamofire
class CurrentWeatherVC: UIViewController {
@IBOutlet weak var locationLabel: UILabel!
@IBOutlet weak var weatherIcon: UIImageView!
@IBOutlet weak var currentTempLabel: UILabel!
@IBOutlet weak var weatherTypeLabel: UILabel!
var currentWeather : CurrentWeather!
override func viewDidLoad() {
super.viewDidLoad()
Location.sharedInstance.locationManager(manager: Location.sharedInstance.locationManager, didChangeAuthorizationStatus: .authorizedWhenInUse)
currentWeather = CurrentWeather()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Location.sharedInstance.startUpdatingLocation()
currentWeather.downloadWeatherDetails {
self.updateMainUI()
}
}
func updateMainUI() {
//Double value convterted to string for current temp.
//Added the degree symbol here
//For forecast it gets added in before saved into list so be aware of that.
currentTempLabel.text = "\(currentWeather.currentTemp)°"
weatherTypeLabel.text = currentWeather.weatherType
locationLabel.text = currentWeather.cityName
weatherIcon.image = UIImage(named: currentWeather.weatherType)
}
}
Je ne vérifie pas l'état actuel d'autorisation; il suffit de demander l'autorisation d'utilisation à chaque fois. iOS invite l'utilisateur une seule fois. – Paulw11
@ Paulw11 ouais j'ai essayé de le demander aussi, et le même problème persiste. L'alerte ne s'affichera pas jusqu'à ce que je clique sur le bouton d'accueil et quitte l'application. Dans l'alerte de simulateur apparaît correctement, ce qui est étrange. Peut-être que cela a quelque chose à voir avec la vue de ne pas charger dans la vue principale? – mufc
Il semble que vous bloquiez le thread principal ou que vous mettiez à jour l'interface utilisateur à partir d'un thread d'arrière-plan. Vous appelez la méthode delegate de votre contrôleur de vue, ce que vous ne devriez pas faire. Seul 'CLLocationManager' devrait appeler ses fonctions de délégué. – Paulw11