2017-07-10 4 views
0

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) 
    } 

} 
+0

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

+0

@ 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

+0

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

Répondre

0

je soupçonne que la mise en œuvre de downloadWeatherDetails utilise un dataTask ou l'une des autres méthodes NSURLSession qui fonctionnent en arrière-plan.

Assurez-vous d'appeler des choses que l'interface utilisateur sur le mainQueue:

// ... 
DispatchQueue.main.async { 
    self.updateMainUI() 
} 
// ...