0

My iOS app has been rejected by Apple as the app crashes if a user selected "Dont allow" location access. And the proceeds to tap on my Map button.

How can I wrap this button in check to see if the user has given permission, And if not how can I ask for permission again?

//Map Button Action - Opens Maps - Gives choice of Google or Apple maps
  @IBAction func googleMapBtn(_ sender: UIButton) {
    UIDevice.current.isBatteryMonitoringEnabled = true
    let state = UIDevice.current.batteryState
    //If user is in Loop - Cant open maps
    if state == .charging {
      print("In Loop - Cant open maps")
    }
      //Present Map Options
    else {
      let alertController = UIAlertController.init(title: "Open Map", message: "", preferredStyle: .alert)
      alertController.addAction(UIAlertAction.init(title: "Google Maps", style: .default, handler: { (action) in
        self.googleMapsOpen()
      }))
      alertController.addAction(UIAlertAction.init(title: "Apple Maps", style: .default, handler: { (action) in
        self.appleMapsOpen()
      }))
      alertController.addAction(UIAlertAction.init(title: "Back", style: .default, handler: { (action) in
        self.dismiss(animated: true, completion: nil)
      }))
      self.present(alertController, animated: true) {
      }
    }
  }

The code crashes whenever a user selects a map type Google/Apple and the self.googleMapsOpen() or self.appleMapsOpen() are executed. Specifically is crashed on the let scheme=

func googleMapsOpen(){
    print("Google Maps Pressed")
    let scheme  = "comgooglemaps://?center=\(LocationManager.sharedInstance.location.coordinate.latitude),\(LocationManager.sharedInstance.location.coordinate.longitude)&zoom=15"
    self.open(scheme: scheme)
}

func appleMapsOpen(){
    print("Apple Maps Pressed")
    let scheme  = "http://maps.apple.com/?ll=\(LocationManager.sharedInstance.location.coordinate.latitude),\(LocationManager.sharedInstance.location.coordinate.longitude)&zoom=15"
    self.open(scheme: scheme)
}
  • 1
    Where in this code do you use the user location, and do you know on what line your app crashes? – Rengers Oct 23 '18 at 09:33
  • @Rengers This is all that apple said "Your app crashed on iPhone running iOS 12.0.1 connected to an IPv6 network if we try to use the maps feature when we tapped "Don't Allow" when prompted for permission to use current location. If location information is required, it is necessary to display a notification or alert indicating this requirement." – Oliver Ferris Oct 23 '18 at 09:44
  • I have also tested it out and sure enough if I chose to not allow location permission and try to open one one of the map buttons the app will crash – Oliver Ferris Oct 23 '18 at 09:44
  • Right, so if you can reproduce the crash, you can find out which line your app crashes on. You can't get iOS to prompt for permission again. You can check the permissions on `CLLocationManager` and show an alert to the user, prompting them to open the app settings if permission is denied. – Paulw11 Oct 23 '18 at 09:46
  • @Paulw11 I've updated my question to show where its crashing – Oliver Ferris Oct 23 '18 at 09:51
  • What is the exception message? Those lines shouldn't crash unless there is an implicitly unwrapped optional in there somewhere that you haven't shown. You should check the location authorisation status and either disable the button or show an alert as I suggested – Paulw11 Oct 23 '18 at 09:55
  • Ive Tried using the following line to check the status of location authorisation, But it doesn't work if CLLocationManager.locationServicesEnabled() { } – Oliver Ferris Oct 23 '18 at 10:15
  • This is the exception message "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" – Oliver Ferris Oct 23 '18 at 10:16

1 Answers1

1

You can do something like this :

func checkLocationPermissionEnabled()
    {
        if CLLocationManager.locationServicesEnabled()
        {
            switch(CLLocationManager.authorizationStatus())
            {
            case .notDetermined, .restricted, .denied:
                self.openDeviceLocationSetting()
                return
            case .authorizedAlways, .authorizedWhenInUse:
                //do whatever you want to do with location
                return
            }
        }
        else
        {
            self.openDeviceLocationSetting()
            return
        }
    }


    func openDeviceLocationSetting()
    {
        let alertController = UIAlertController(title: "", message:"For best results, let your device turn on location using Google's location service.", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
            UIAlertAction in
            self.isAlertShowing = false
            let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
            if let url = settingsUrl {
                UIApplication.shared.openURL(url as URL)
            }
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default) {
            UIAlertAction in

        }
        alertController.addAction(okAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
    }
Shruti Thombre
  • 989
  • 4
  • 11
  • 27