Swift 4 - 更新隐私设置 CLLocationManager 后刷新视图
Swift 4 - Refresh View after updating privacy settings CLLocationManager
我正在创建一个基于位置的应用程序,当用户拒绝位置访问时,会弹出一个警告视图,要求用户转到设置页面并更新设置以允许位置访问。如果用户允许访问然后按回键,则视图不会使用允许更新位置的更新设置刷新。
在用户从设置页面返回应用程序后,是否有功能可以 运行 刷新并开始更新位置。
感谢任何建议或帮助。谢谢。
用户看到提醒:
用户点击返回应用程序后,页面需要刷新以更新地图上的位置:
func alertForNoLocationAccess(){
let alert = UIAlertController(title: "Allow Location Access", message: "Cannot add location data and map coordinates to your entries without access. Press settings to update or cancel to deny access.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Settings", style: .default, handler: { action in
if let url = URL(string:UIApplication.openSettingsURLString) {
if UIApplication.shared.canOpenURL(url) {
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
}
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true)
}
将 ViewController/AppDelegate
注册到 NotificationCenter
以在用户从 Settings
打开应用程序时收到通知。
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
在用户打开应用程序时,再次请求位置更新到 CLLocationManager
。如果用户已经接受了请求,那么 CLLocationManager
将开始更新用户的位置而不会中断。
@objc func willEnterForeground() {
//Register for
registerForLocationUpdates()
}
func registerForLocationUpdates() {
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
查看 Apple 的文档,您会发现:
"When you request authorization, or when your app's authorization
status changes, use the locationManager(_:didChangeAuthorization:)
method of your delegate object to process the changes. Listing 3 shows
an implementation of that method that enables or disables features
based on the app's current authorization level."
显然,如果用户决定关闭您获取位置数据的权限,此委托方法也会被触发。
如果您显示此提醒,您还应该使用此通知关闭提醒,以防用户在未使用提醒中的按钮的情况下手动转到“设置”。
实现CLLocationManagerDelegate的Delegate方法
// MARK: - CLLocationManagerDelegate
extension LocationTracker: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
guard let location = locations.first else { return }
lastLocation = location
print(LocationTracker.shared.lastLocation)
print("location = \(location.coordinate.latitude) \(location.coordinate.longitude)")
locateMeCallback?(location)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
enableLocationServices()
}
}
/// enableLocationService 是这样的
func enableMyAlwaysFeatures() {
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = true
locationManager.startUpdatingLocation()
locationManager.delegate = self
}
我正在创建一个基于位置的应用程序,当用户拒绝位置访问时,会弹出一个警告视图,要求用户转到设置页面并更新设置以允许位置访问。如果用户允许访问然后按回键,则视图不会使用允许更新位置的更新设置刷新。
在用户从设置页面返回应用程序后,是否有功能可以 运行 刷新并开始更新位置。
感谢任何建议或帮助。谢谢。
用户看到提醒:
用户点击返回应用程序后,页面需要刷新以更新地图上的位置:
func alertForNoLocationAccess(){
let alert = UIAlertController(title: "Allow Location Access", message: "Cannot add location data and map coordinates to your entries without access. Press settings to update or cancel to deny access.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Settings", style: .default, handler: { action in
if let url = URL(string:UIApplication.openSettingsURLString) {
if UIApplication.shared.canOpenURL(url) {
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
}
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true)
}
将 ViewController/AppDelegate
注册到 NotificationCenter
以在用户从 Settings
打开应用程序时收到通知。
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
在用户打开应用程序时,再次请求位置更新到 CLLocationManager
。如果用户已经接受了请求,那么 CLLocationManager
将开始更新用户的位置而不会中断。
@objc func willEnterForeground() {
//Register for
registerForLocationUpdates()
}
func registerForLocationUpdates() {
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
查看 Apple 的文档,您会发现:
"When you request authorization, or when your app's authorization status changes, use the locationManager(_:didChangeAuthorization:) method of your delegate object to process the changes. Listing 3 shows an implementation of that method that enables or disables features based on the app's current authorization level."
显然,如果用户决定关闭您获取位置数据的权限,此委托方法也会被触发。
如果您显示此提醒,您还应该使用此通知关闭提醒,以防用户在未使用提醒中的按钮的情况下手动转到“设置”。
实现CLLocationManagerDelegate的Delegate方法
// MARK: - CLLocationManagerDelegate
extension LocationTracker: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
guard let location = locations.first else { return }
lastLocation = location
print(LocationTracker.shared.lastLocation)
print("location = \(location.coordinate.latitude) \(location.coordinate.longitude)")
locateMeCallback?(location)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
enableLocationServices()
}
}
/// enableLocationService 是这样的
func enableMyAlwaysFeatures() {
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = true
locationManager.startUpdatingLocation()
locationManager.delegate = self
}