2017-07-10 5 views
0

Ich habe eine Singleton-Klasse für die Standortautorisierung erstellt, weil ich sie für mehrere Ansichten in meiner App benötigte. Also habe ich die folgende Location.swift-Klasse erstellt.Standortautorisierungswarnung wird angezeigt, nachdem App geschlossen wurde

ANMERKUNG: Ich habe richtig in Info.plist hinzugefügt und haben an mehreren anderen Stellen, aber keiner sah scheinen diese (zumindest keine gefunden) zu adressieren

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

    } 


} 

Meine App abstürzt, und ich denke, weil die Standortautorisierung nicht am Anfang festgelegt ist. Das Lustige daran ist, dass die Anforderungswarnung, die den Benutzer dazu auffordert, Lokalisierungsdienste zuzulassen, erst angezeigt wird, wenn Sie die App verlassen.

Sobald Sie die App schließen und die Standortdienste akzeptieren, funktioniert die App einwandfrei. Meine Frage ist also, warum erscheint die Warnung nicht?

ist es auch interessant zu beachten, dass dies nur durch ein tatsächliches Gerät auftritt. Im Simulator erscheint die Warnung wie erwartet, wenn die Startansicht geladen wird.

meine erste Ansicht, die angeblich auf und zeigen Daten zu laden ist wie folgt:

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

ich den aktuellen Zulassungsstatus nicht überprüfen würde; nur wenn Erlaubnis in jedem Mal anfordern. iOS wird den Benutzer nur einmal auffordern. – Paulw11

+0

@ Paulw11 yeah Ich habe versucht, es auch nur, und das gleiche Problem besteht weiterhin. Warnung wird nicht angezeigt, bis ich auf den Home-Button klicke und die App verlasse. Im Simulator erscheint die Warnung richtig, was seltsam ist. Vielleicht hat es etwas damit zu tun, dass die Ansicht nicht in der Hauptansicht geladen wird? – mufc

+0

Es hört sich so an, als würden Sie den Hauptthread blockieren oder die Benutzeroberfläche von einem Hintergrundthread aus aktualisieren. Sie rufen die Delegate-Methode von Ihrem View-Controller aus auf, was Sie nicht tun sollten. Nur der 'CLLocationManager' sollte seine Delegiertenfunktionen aufrufen. – Paulw11

Antwort

0

I downloadWeatherDetails s Implementierung vermuten ein dataTask oder eine der anderen NSURLSession Methoden verwendet, die im Hintergrund laufen.

Stellen Sie sicher, nur UI Zeug rufen die mainQueue:

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