CLLocationManager crashes when Authorization Status Change in Background

Hi all as topic title, my app crash whenever I do the following Steps:


1) Just installed the app (iOS 8 and above only)

2) Click a button that will prompt for Location Service Authorization

3) Deny access

4) An error shows (Correct)

5) Go to Settings -> Application Settings -> Allows Location Service Access

6) Crash! (In my iPhone 5S in iOS 9.2.1)


Here's the code that lead to enabling the Location Service part:


private func initLocationManager() {
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        startLocationManger()
    }

    private func startLocationManger(){
  
        if(autoUpdate){
      
            locationManager.startUpdatingLocation()
        }else{
      
            locationManager.startMonitoringSignificantLocationChanges()
        }
  
        isRunning = true
  
    }



I have no idea whats happening or was there some other code is the culprit??...


    func locationManagerStatus(status:NSString){
        //Delegate method
      
        LMStatus = status as String
      
        if (status == NSLocalizedString("DN", comment: "Denied access")){
            /
            LMVerbose = NSLocalizedString("verbose-DN", comment: "You have explicitly denied authorization for this application, or location services are disabled in Settings.")
        } else if (status == NSLocalizedString("RT", comment: "Restricted Access")){
            /
            LMVerbose = NSLocalizedString("verbose-RT", comment: "This application is not authorized to use location services. Due to active restrictions on location services, the user cannot change this status, and may not have personally denied authorization.")
        } else if (status == NSLocalizedString("ND", comment: "Not Determined")){
          
            LMVerbose = NSLocalizedString("verbose-ND", comment: "You have not yet made a choice with regards to this application.")
        } else if (status == NSLocalizedString("AA", comment: "Allowed access")){
            LMVerbose = NSLocalizedString("verbose-AA", comment: "App is Authorized to use location services.")
        }
      
      
    }




func getGPSCoordinates(completion:(ReceivedResult: Bool, ReceivedErrorMessage: String?, latitude: Double?, longitude: Double?) -> Void){
   
        var ReceivedResult = false
        var ReceivedErrorMessage = nil as String!
        var Receivedlatitude = 0.0
        var Receivedlongitude = 0.0
   
        let serviceGroup: dispatch_group_t = dispatch_group_create()
   
        dispatch_group_enter(serviceGroup)
   
        locationManager.startUpdatingLocationWithCompletionHandler { (latitude, longitude, status, verboseMessage, error) -> Void in
  
            ReceivedErrorMessage = error
            Receivedlatitude = latitude
            Receivedlongitude = longitude
       
            dispatch_group_leave(serviceGroup)
        }
   
        dispatch_group_notify(serviceGroup, dispatch_get_main_queue(), {() -> Void in
            /
       
            if (ReceivedErrorMessage != nil){
                ReceivedResult = false
                 completion(ReceivedResult: ReceivedResult, ReceivedErrorMessage: ReceivedErrorMessage, latitude: Receivedlatitude, longitude: Receivedlongitude)
           
           
            } else {
               ReceivedResult = true
completion(ReceivedResult: ReceivedResult, ReceivedErrorMessage: ReceivedErrorMessage, latitude: Receivedlatitude, longitude: Receivedlatitude)
            }
        })
    }


    func GetCurrentLocationGPS(completion:()){
        var receivedStartlat = nil as Double!
        var receivedStartlong = nil as Double!
        var result = false
        var message = nil as String!
   
   
        let serviceGroup: dispatch_group_t = dispatch_group_create()
   
        dispatch_group_enter(serviceGroup)
   
        if (self.LMStatus == NSLocalizedString("AA", comment: "Allowed access")  || self.LMStatus == NSLocalizedString("ND", comment: "Not Determined")){
   
            getGPSCoordinates() {  (ReceivedResult: Bool, ReceivedErrorMessage: String?, latitude: Double?, longitude: Double?) in
       
                 receivedStartlat = latitude
                 receivedStartlong = longitude
                 result = ReceivedResult
                 message = ReceivedErrorMessage          
                 dispatch_group_leave(serviceGroup)
            }
        } else {
            result = false
            message = self.LMVerbose
            dispatch_group_leave(serviceGroup)
        }
   
   
        dispatch_group_notify(serviceGroup, dispatch_get_main_queue(), {() -> Void in
       
          
            self.locationManager.stopUpdatingLocation()
       
            if(result == false){
                self.CurrentLocation.text! = message!
           
            } else {
           
               self.Startlat = receivedStartlat
               self.Startlong = receivedStartlong
               print(self.Startlat)
  print(self.Startlong)
            }
            completion;
       
        })
    }



LocationManagerStatus is activated as delegate with this function:


internal func locationManager(manager: CLLocationManager,
        didChangeAuthorizationStatus status: CLAuthorizationStatus) {
            var hasAuthorised = false
            let verboseKey = status
            switch status {
            case CLAuthorizationStatus.Restricted:
                locationStatus = NSLocalizedString("RT", comment: "Restricted Access")
                break
            case CLAuthorizationStatus.Denied:
                locationStatus = NSLocalizedString("DN", comment: "Denied access")
                break
            case CLAuthorizationStatus.NotDetermined:
                locationStatus = NSLocalizedString("ND", comment: "Not determined")
                break
            default:
                locationStatus = NSLocalizedString("AA", comment: "Allowed access")
                hasAuthorised = true
                break
            }
           
            verboseMessage = verboseMessageDictionary[verboseKey]!
           
            if (hasAuthorised == true) {
                startLocationManger()
            }else{
               
                resetLatLon()
                if (!locationStatus.isEqualToString(NSLocalizedString("DN", comment: "Denied access"))){
                   
                    var verbose = ""
                    if showVerboseMessage {
                       
                        verbose = verboseMessage
                       
                        if ((delegate != nil) && (delegate?.respondsToSelector(Selector("locationManagerVerboseMessage:")))!){
                           
                            delegate?.locationManagerVerboseMessage!(verbose)
                           
                        }
                    }
                   
                    if(completionHandler != nil){
                        completionHandler?(latitude: latitude, longitude: longitude, status: locationStatus as String, verboseMessage:verbose,error: nil)
                    }
                }
                if ((delegate != nil) && (delegate?.respondsToSelector(Selector("locationManagerStatus:")))!){
                    delegate?.locationManagerStatus!(locationStatus)
                }
            }
           
    }

What does the crash log say? (What line is it crashing on?)

Hi, thanks for the help. However this is what I see:


libdispatch.dylib`dispatch_group_leave:
    0x10121ec7c <+0>:  add    x10, x0, #64
    0x10121ec80 <+4>:  ldxr  x9, [x10]
    0x10121ec84 <+8>:  add    x8, x9, #1
    0x10121ec88 <+12>: stlxr  w11, x8, [x10]
    0x10121ec8c <+16>: cbnz  w11, 0x10121ec7c          ; <+0>
    0x10121ec90 <+20>: cmn    x9, #2
    0x10121ec94 <+24>: b.le  0x10121ecb0              ; <+52>
    0x10121ec98 <+28>: orr    x9, xzr, #0x7fffffffffffffff
    0x10121ec9c <+32>: cmp    x8, x9
    0x10121eca0 <+36>: b.ne  0x10121ecac              ; <+48>
    0x10121eca4 <+40>: orr    w1, wzr, #0x1
    0x10121eca8 <+44>: b      0x10122bc9c              ; _dispatch_group_wake
    0x10121ecac <+48>: ret
    0x10121ecb0 <+52>: stp    x20, x21, [sp, #-16]!
    0x10121ecb4 <+56>: adrp  x20, 41
    0x10121ecb8 <+60>: add    x20, x20, #3579
    0x10121ecbc <+64>: adrp  x21, 46
    0x10121ecc0 <+68>: add    x21, x21, #3272
    0x10121ecc4 <+72>: str    x20, [x21]
    0x10121ecc8 <+76>: ldp    x20, x21, [sp], #16
->  0x10121eccc <+80>: brk    #0x1


The last line shows: Thread1: EXC_BREAKPOINT (code=1, subcode=0x10121eccc)


Upon closer inspection, the problematic code is here:

locationManager.startUpdatingLocationWithCompletionHandler { (latitude, longitude, status, verboseMessage, error) -> Void in
            ReceivedErrorMessage = error
            Receivedlatitude = latitude
            Receivedlongitude = longitude
  
            dispatch_group_leave(serviceGroup)
        }



My button goes to GetCurrentLocationGPS() which will allow me to use complete:(), such that I can initialize the values and process when to show alert.


The main getting GPS coordinates is in getGPSCoordinates() which will call locationManager.startUpdatingLocationWithCompletionHandler.


Somehow, this locationManager.startUpdatingLocationWithCompletionHandler cannot stop update location despite I have executed self.locationManager.stopUpdatingLocation() first before went to re-enable Location Service's permission.



The only warning I got was: "Warning: Unable to create restoration in progress marker file".


But then, this warning I got was merely start the app where I did not request nor use any location service at all until I pressed this particular button.


Even that, I have an unique Storyboard ID for all ViewControllers and unique Restore ID for all UI items (Textfield, Buttons, View, Scroll View etc.) with my app delegate files includes:


  
    func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
        return true
    }
   
    func application(application: UIApplication, shouldSaveApplicationState coder:NSCoder) -> Bool{
        return true;
    }
   
    func application(application: UIApplication, shouldRestoreApplicationState coder:NSCoder) -> Bool{
        return true;
    }

Sorry I can't help you with that. I always use dispatch_async() myself so I have no idea about how those dispatch_group_* calls work.

CLLocationManager crashes when Authorization Status Change in Background
 
 
Q