2016-12-03 1 views
0

Благодаря совету Томаса ниже я изменил свой код с исходного запроса. Мне интересно, пытаюсь ли я сделать что-то невозможное или, если нет, как я могу это сделать.Пересмотреть CLLocationManager.authorizationStatus в запуске приложения после изменения настроек местоположения приложения

Если у пользователя нет авторизированных служб определения местоположения, я вызываю их с помощью кнопки «Открыть настройки», чтобы изменить настройки местоположения приложения. Это работает. Но после возврата из настроек в приложение я хотел бы узнать, было ли внесено изменение и активировать службы определения местоположения. Это можно сделать? Закрытие ниже успешно приводит пользователя к настройкам приложения, пользователь может вносить изменения, и пользователь может вернуться, но закрытие срабатывает, когда пользователь нажимает «Открыть настройки», который до того, как настройки были изменены. BTW: Если есть лучший способ справиться с подталкиванием пользователя к утверждению анонимных предпочтений приложения в настоящее время, я был бы признателен за совет. Благодаря!

locationManager.requestWhenInUseAuthorization() // request authorization 

let authStatus = CLLocationManager.authorizationStatus() 

switch authStatus { 
    case .denied: 
     let alertController = UIAlertController(title: "Background Location Access Disabled", message: "In order to show the location weather forecast, please open this app's settings and set location access to 'While Using'.", preferredStyle: .alert) 
     alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) 
     alertController.addAction(UIAlertAction(title: "Open Settings", style: .`default`, handler: { action in 
      if #available(iOS 10.0, *) { 
       let settingsURL = URL(string: UIApplicationOpenSettingsURLString)! 
       UIApplication.shared.open(settingsURL, options: [:], completionHandler: {(success) in 
        print("*** Success closure fires") 
        let newAuthStatus = CLLocationManager.authorizationStatus() 
        switch newAuthStatus { 
        case .authorizedWhenInUse: 
         self.locationManager.startUpdatingLocation() 
        default: 
         print("Not .authorizedWhenInUse") 
        } 
       }) 
      } else { 
       if let url = NSURL(string:UIApplicationOpenSettingsURLString) { 
        UIApplication.shared.openURL(url as URL) 
       } 
      } 
     })) 
     self.present(alertController, animated: true, completion: nil) 

    case .authorizedWhenInUse, .authorizedAlways: 
     locationManager.startUpdatingLocation() 
    case .restricted : 
     print("App is restricted, likely via parental controls.") 
    default: 
     print("UH!! WHAT OTHER CASES ARE THERE? ") 
    } 
+0

Я думаю, что вы недоразумение является 'present' метод. Запуск будет запущен, когда будет представлен контроллер просмотра. Я немного неясен из вашего описания, но похоже, что вы хотите, чтобы это действие было запущено после того, как пользователь выбрал один из параметров оповещения, поэтому этот код должен быть в одном из обработчиков завершения UIAlertAction. –

+0

Спасибо, Томас. Это было полезно. Мне удалось переместить мое закрытие и выполнить его, когда пользователь нажал кнопку «Открыть настройки». Но мне интересно, могу ли я спросить невозможное. Я надеюсь снова проверить авторизацию, когда пользователь вернется в приложение из настроек приложения через: UIApplicationOpenSettingsURLString. Возможно ли как-то пожаробезопасность, когда пользователь вернется с изменения настроек и проверьте, есть ли у нас авторизация? Еще раз спасибо за ваш совет! – Gallaugher

ответ

1

Я думаю, что код расширения здесь выполняет то, что я хочу - простое расположение получить, но которая обрабатывает все случаи статуса авторизации: - .notDetermined: requestWhenInUseAuthorization - .authorized: startUpdatingLocations - .denied: Подскажите пользователя с предупреждением, которое использует UIApplicationOpenSettingsURLString, чтобы открыть настройки конфиденциальности/местоположения приложения, чтобы они могли внести изменения. Возврат к приложению с новым статусом забирается в didUpdateLocations, поэтому местоположение пользователя фиксируется после обновления настроек. - .restricted - отображается предупреждение, предлагающее пользователю проверить с родителем или системным администратором, чтобы снять ограничения приложения.

Alert также показывает w/код ошибки, если didFailWithError.

Просто установите переменные экземпляра для locationManager & CurrentLocation

let locationManager = CLLocationManager() 
var currentLocation: CLLocation! 

и в viewDidLoad установить делегат & вызова getLocation()

locationManager.delegate = само getLocation()

Надеюсь, это звучит, но лучше всего подходит для этого. Надеюсь, что это помогает кому-то, поскольку я изо всех сил пытался найти что-то, что было в Swift 3 &. Еще раз спасибо, Томас!

расширение ViewController: CLLocationManagerDelegate {

func getLocation() { 

    let status = CLLocationManager.authorizationStatus() 

    handleLocationAuthorizationStatus(status: status) 
} 

func handleLocationAuthorizationStatus(status: CLAuthorizationStatus) { 
    switch status { 
    case .notDetermined: 
     locationManager.requestWhenInUseAuthorization() 
    case .authorizedWhenInUse, .authorizedAlways: 
     locationManager.startUpdatingLocation() 
    case .denied: 
     print("I'm sorry - I can't show location. User has not authorized it") 
     statusDeniedAlert() 
    case .restricted: 
     showAlert(title: "Access to Location Services is Restricted", message: "Parental Controls or a system administrator may be limiting your access to location services. Ask them to.") 
    } 
} 

func showAlert(title: String, message: String) { 
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 

    let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil) 

    alertController.addAction(defaultAction) 

    present(alertController, animated: true, completion: nil) 
} 

func statusDeniedAlert() { 
    let alertController = UIAlertController(title: "Background Location Access Disabled", message: "In order to show the location weather forecast, please open this app's settings and set location access to 'While Using'.", preferredStyle: .alert) 
    alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) 
    alertController.addAction(UIAlertAction(title: "Open Settings", style: .`default`, handler: { action in 
     if #available(iOS 10.0, *) { 
      let settingsURL = URL(string: UIApplicationOpenSettingsURLString)! 
      UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil) 
     } else { 
      if let url = NSURL(string:UIApplicationOpenSettingsURLString) { 
       UIApplication.shared.openURL(url as URL) 
      } 
     } 
    })) 
    self.present(alertController, animated: true, completion: nil) 
} 

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 
    handleLocationAuthorizationStatus(status: status) 
} 

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    if let currentLocation = locations.last { 
     print("My coordinates are: \(currentLocation.coordinate.latitude), \(currentLocation.coordinate.longitude)") 
     locationManager.stopUpdatingLocation() 
     updateUserInterface() 
    } 
} 

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { 
    showAlert(title: "Location Access Failure", message: "App could not access locations. Loation services may be unavailable or are turned off. Error code: \(error)") 
} 

}

Смежные вопросы