Closed realityexpander closed 7 months ago
It's not possible with the current code but should be easy to add a call to CLLocationManager.requestLocation() to request the current location. I don't have time to look at this this week but I don't think it'll be hard -- will take a look as soon as I can. The trick in Python is that because this method returns immediately (the location request is asynchronous), you need to create a threading event and then call the event's set()
in the callback that requestLocation
will call.
But of course, you'll have the same limitations as Locationator does -- you can't do this from the command line alone as the app needs to be able to request the proper permissions which can be done only through the GUI. But Locationator could easily provide a REST API endpoint your CLI could call (which is what it does now).
But Locationator could easily provide a REST API endpoint your CLI could call (which is what it does now).
I'm looking at the docs and don't see where I can make that API call to the server... am I missing something?
I only see the Geocoding calls.
I took a quick stab at this but it failed with error. Will explore when I have more time (working on my taxes though I'd rather be working on this ;-) ) Requesting the location calls the delegate (which in Locationator is the main Locationator class) but it gives an error. Here's the diff if you want to work on this:
diff --git a/locationator/locationator.py b/locationator/locationator.py
index 4b53ce9..afb1682 100644
--- a/locationator/locationator.py
+++ b/locationator/locationator.py
@@ -129,6 +129,9 @@ class Locationator(rumps.App):
self.menu_reverse_geocode = rumps.MenuItem(
"Reverse geocode...", callback=self.on_reverse_geocode
)
+ self.menu_current_location = rumps.MenuItem(
+ "Current location", callback=self.on_current_location
+ )
self.menu_about = rumps.MenuItem(f"About {APP_NAME}", callback=self.on_about)
self.menu_quit = rumps.MenuItem(f"Quit {APP_NAME}", callback=self.on_quit)
self.menu_start_on_login = rumps.MenuItem(
@@ -141,6 +144,7 @@ class Locationator(rumps.App):
self.menu = [
# self.menu_auth_status,
self.menu_reverse_geocode,
+ self.menu_current_location,
None,
self.menu_start_on_login,
self.menu_install_tools,
@@ -250,6 +254,13 @@ class Locationator(rumps.App):
location, _geocode_completion_handler
)
+ def on_current_location(self, sender):
+ """Request current location from Location Services"""
+ NSLog(str(self.location_manager.authorizationStatus()))
+ self.location_manager.startUpdatingLocation()
+ # self.location_manager.requestLocation()
+ # self.location_manager.stopUpdatingLocation()
+
def on_install_remove_tools(self, sender):
"""Install or remove the command line tools"""
if sender.title.startswith("Install"):
@@ -598,6 +609,15 @@ class Locationator(rumps.App):
open_kwargs["encoding"] = encoding
return open(*open_args, **open_kwargs)
+ def locationManager_didUpdateLocations_(
+ self, manager: CLLocationManager, locations: list[CLLocation]
+ ):
+ """Called when location is updated"""
+ self.log(f"didUpdateLocations: {manager} {locations}")
+
+ def locationManager_didFailWithError_(self, manager: CLLocationManager, error: Any):
+ """Handle errors from CLLocationManager"""
+ self.log(f"locationManager_didFailWithError_: {manager} {error}")
def placemark_to_dict(placemark: CLPlacemark) -> dict:
"""Convert a CLPlacemark to a dict
Unfortunately, I’m as newbie on iOS. My primary is Android Native and then web dev. I’m new to iOS when I started working the Kotlin Multi-platform, so I have zero experience with Objective-C.
Thanks for the quick update! Chris
On Apr 7, 2024, at 5:12 PM, Rhet Turnbull @.***> wrote:
I took a quick stab at this but it failed with error. Will explore when I have more time (working on my taxes though I'd rather be working on this ;-) ) Requesting the location calls the delegate (which in Locationator is the main Locationator class) but it gives an error. Here's the diff if you want to work on this:
diff --git a/locationator/locationator.py b/locationator/locationator.py index 4b53ce9..afb1682 100644 --- a/locationator/locationator.py +++ b/locationator/locationator.py @@ -129,6 +129,9 @@ class Locationator(rumps.App): self.menu_reverse_geocode = rumps.MenuItem( "Reverse geocode...", callback=self.on_reverse_geocode )
self.menu_current_location = rumps.MenuItem(
"Current location", callback=self.on_current_location
) self.menu_about = rumps.MenuItem(f"About {APP_NAME}", callback=self.on_about) self.menu_quit = rumps.MenuItem(f"Quit {APP_NAME}", callback=self.on_quit) self.menu_start_on_login = rumps.MenuItem( @@ -141,6 +144,7 @@ class Locationator(rumps.App): self.menu = [
self.menu_auth_status,
self.menu_reverse_geocode,
self.menu_current_location, None, self.menu_start_on_login, self.menu_install_tools, @@ -250,6 +254,13 @@ class Locationator(rumps.App): location, _geocode_completion_handler )
def on_current_location(self, sender):
"""Request current location from Location Services"""
NSLog(str(self.location_manager.authorizationStatus()))
self.location_manager.startUpdatingLocation()
self.location_manager.requestLocation()
self.location_manager.stopUpdatingLocation()
def on_install_remove_tools(self, sender): """Install or remove the command line tools""" if sender.title.startswith("Install"): @@ -598,6 +609,15 @@ class Locationator(rumps.App): open_kwargs["encoding"] = encoding return open(*open_args, **open_kwargs)
def locationManagerdidUpdateLocations(
self, manager: CLLocationManager, locations: list[CLLocation]
):
"""Called when location is updated"""
self.log(f"didUpdateLocations: {manager} {locations}")
def locationManagerdidFailWithError(self, manager: CLLocationManager, error: Any):
"""Handle errors from CLLocationManager"""
self.log(f"locationManagerdidFailWithError: {manager} {error}")
def placemark_to_dict(placemark: CLPlacemark) -> dict: """Convert a CLPlacemark to a dict — Reply to this email directly, view it on GitHub https://github.com/RhetTbull/locationator/issues/12#issuecomment-2041625235, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHLEYQJHTDS5GPZVEDFY4LY4HAGHAVCNFSM6AAAAABF3S465GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANBRGYZDKMRTGU. You are receiving this because you authored the thread.
I figured this out. Working on an update but may be a few days.
WOW! That’s amazing to hear!
I went thru at least 6 different approaches to this seemingly simple problem, but after Ventura, this is very locked down.
Anyway, I have no rush on this, and it’s good to hear you are working on this as it seems yours will be the only solution for using the command line to access the current GPS location.
Best, Chris
On Apr 9, 2024, at 2:13 PM, Rhet Turnbull @.***> wrote:
I figured this out. Working on an update but may be a few days.
— Reply to this email directly, view it on GitHub https://github.com/RhetTbull/locationator/issues/12#issuecomment-2045896315, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHLEYQ7GPDPLL7ALX4NWADY4Q4WNAVCNFSM6AAAAABF3S465GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANBVHA4TMMZRGU. You are receiving this because you authored the thread.
I've got this partially working. I can get the location once but subsequent calls produce an error. Once I figure it out, the API will look the following so you can hit the API from any app that can make an HTTP request and get back a JSON object with location:
http GET localhost:8000/current_location
Content-type: text/plain
Date: Fri, 12 Apr 2024 13:11:27 GMT
Server: SimpleHTTP/0.6 Python/3.11.7
{
"altitude": 0.0,
"course": -1.0,
"error": null,
"horizontal_accuracy": 35.0,
"latitude": 38.82347632466596,
"longitude": -104.64334336698116,
"speed": -1.0,
"timestamp": "2024-04-12T07:11:27.528566",
"vertical_accuracy": -1.0
}
WOW! Amazing… Returning a cached result and error code would be acceptable, or maybe that should be up to the user’s application (im imagining here)
Thanks for the update and I look forward to using your project!
Chris
On Apr 12, 2024, at 8:13 AM, Rhet Turnbull @.***> wrote:
I've got this partially working. I can get the location once but subsequent calls produce an error. Once I figure it out, the API will look the following so you can hit the API from any app that can make an HTTP request and get back a JSON object with location:
http GET localhost:8000/current_location Content-type: text/plain Date: Fri, 12 Apr 2024 13:11:27 GMT Server: SimpleHTTP/0.6 Python/3.11.7
{ "altitude": 0.0, "course": -1.0, "error": null, "horizontal_accuracy": 35.0, "latitude": 38.82347632466596, "longitude": -104.64334336698116, "speed": -1.0, "timestamp": "2024-04-12T07:11:27.528566", "vertical_accuracy": -1.0 } — Reply to this email directly, view it on GitHub https://github.com/RhetTbull/locationator/issues/12#issuecomment-2051739039, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHLEYWTBLE4DBU76G7VZNLY47MYFAVCNFSM6AAAAABF3S465GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANJRG4ZTSMBTHE. You are receiving this because you authored the thread.
Implemented in release 0.2.0. See docs here for new /current_location
endpoint.
@all-contributors please add @realityexpander for ideas
@RhetTbull
I've put up a pull request to add @realityexpander! :tada:
Thanks again for doing this!
I have been scouring the web for a solution that allows CLI to access the location info, and surprisingly, this topic seems to be "not a thing" due to increased permissions by Apple OS's lately...
Getting this info in the browser is trivial.
Any hints about this?