私はアプリでいくつかのビューに必要なため、ロケーション認可を処理するシングルトンクラスを作成しました。そこで私は以下のLocation.swiftクラスを作成しました。アプリが終了した後にロケーション認可の警告が表示される
注:私は、Info.plistのに正しく追加されている、および他の記事が、どれもいくつか見てきましたが、この(私が見つけた、少なくともどれも)
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()
}
}
私のアプリがクラッシュさに対処しないように見える、と私は思います位置認可が最初に設定されていないためです。面白いのは、位置情報サービスを許可するようにユーザーに促すリクエストアラートが、あなたがアプリを離れるまで表示されないということです。
アプリを終了して位置情報サービスを受け入れると、アプリは正常に動作します。だから私の質問は、警告が表示されない理由は何ですか?
これは実際のデバイスでのみ発生していることにも注目してください。シミュレータでは、初期ビューがロードされているときに警告がポップアップします。
ロードするようになって、次のようにショーのデータがあるされて私の最初のビュー:
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)
}
}
私は現在の認証ステータスをチェックしません。毎回使用許可があるときにリクエストしてください。 iOSはユーザーに一度だけプロンプトを表示します。 – Paulw11
@ Paulw11ええ私もそれをリクエストしてみましたが、同じ問題はそのままです。アラートは、ホームボタンをクリックしてアプリを終了するまで表示されません。シミュレータの警告が正しく表示されますが、これは奇妙です。たぶんそれはメインビューに読み込まれないビューと関係があるでしょうか? – mufc
メインスレッドをブロックしているか、バックグラウンドスレッドからUIを更新しているようです。ビューコントローラからデリゲートメソッドを呼び出していますが、これを行うべきではありません。 'CLLocationManager'だけがデリゲート関数を呼び出す必要があります。 – Paulw11