Search code examples
pythonobjective-ccore-location

CoreLocation AttributeError


I am trying to find my Mac's current location using the following python script. It is using the python objective-C bridge and it works sometimes. However sometimes I am getting the following AttributeError and I'm unsure what I should do to fix the error.

#!/usr/bin/python
# encoding: utf-8

import CoreLocation
manager = CoreLocation.CLLocationManager.alloc().init()
manager.delegate()
manager.startUpdatingLocation()
coord = manager.location().coordinate()
lat, lon = coord.latitude, coord.longitude
print lat, lon

Following error:

Traceback (most recent call last):
  File "Desktop/SimpleCoreServices.py", line 11, in <module>
    coord = manager.location().coordinate()
AttributeError: 'NoneType' object has no attribute 'coordinate'

Apple's developer documentation isn't helping me out since my Objective-C isn't that strong.


Solution

  • You should wait until locationd prompts for location access. Then allow python to use location services. I added a wait block to your code:

    import CoreLocation
    from time import sleep
    
    manager = CoreLocation.CLLocationManager.alloc().init()
    manager.delegate()
    manager.startUpdatingLocation()
    while CoreLocation.CLLocationManager.authorizationStatus() != 3 or manager.location() is None:
        sleep(.1)
    coord = manager.location().coordinate()
    lat, lon = coord.latitude, coord.longitude
    print (lat, lon)
    

    The prompt will be shown while the loop is waiting for authorizationStatus and getting a value in location. Sometimes it takes about 30 seconds to show the dialog:

    Location access prompt

    If the user accepts the access by choosing "Allow", the value of authorizationStatus becomes 3. After that, the loop will be continued to wait until a location value obtained.

    Unfortunately, controlling the access via the Security and Privacy section in System Preferences will be impossible sometimes. Because of disappearing the python row in Location Services list, you cannot check or uncheck it. Also, the tccutil shell command cannot control this.

    If you accidentally chose the "Don't Allow" button, it can be reset with these instructions.