2016-12-03 72 views
0

感謝以下Thomas的建議我從原始請求修改了我的代碼。我想知道如果我試圖做一些不可能的事情,或者如果不行,我該如何做到這一點。在應用程序位置設置更改後重新評估正在運行的應用程序中的CLLocationManager.authorizationStatus

如果用戶沒有授權位置服務,我通過一個提示與「打開設置」按鈕來更改應用程序的位置設置。這工作。但是,從設置返回到應用程序,我想確認是否進行了更改並激活位置服務。這可以做到嗎?下面的關閉成功地讓用戶進入應用程序的設置,用戶可以進行更改,用戶可以返回,但是當用戶按下「打開設置」(在設置被更改之前)時觸發關閉。順便說一句:如果有更好的方法來處理用戶批准應用程序當前未授權的位置首選項,我會很感激建議。謝謝!

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 - 顯示一條警告,提示用戶檢查父級或系統管理員以解除應用程序限制。

如果發生didFailWithError,警報還會顯示w /錯誤代碼。

剛剛成立的LocationManager & currentLocation

let locationManager = CLLocationManager() 
var currentLocation: CLLocation! 

和viewDidLoad中的實例變量設置委託&調用的getLocation()

locationManager.delegate =自 的getLocation()

希望這是合理的,但是以更好的方式回答這個問題是最受歡迎的。希望它能幫助別人,因爲我努力尋找全面的東西。再次感謝托馬斯!

擴展視圖控制器: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)") 
} 

}

相關問題