【发布时间】:2017-07-10 12:17:00
【问题描述】:
我创建了一个单例类来处理位置授权,因为我的应用程序中的多个视图都需要它。所以我创建了下面的 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 是的,我也尝试过请求它,但同样的问题仍然存在。在我单击主页按钮并离开应用程序之前,不会弹出警报。在模拟器中警报正确显示,这很奇怪。也许这与视图未在主视图中加载有关?
-
听起来您正在阻塞主线程或从后台线程更新 UI。您正在从视图控制器调用委托方法,您不应该这样做。只有
CLLocationManager应该调用它的委托函数。
标签: ios cllocationmanager cllocation