Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't grant location permissions on MacOs 14 (Sonoma) #50

Open
jedberg opened this issue Jul 18, 2023 · 14 comments
Open

Can't grant location permissions on MacOs 14 (Sonoma) #50

jedberg opened this issue Jul 18, 2023 · 14 comments

Comments

@jedberg
Copy link

jedberg commented Jul 18, 2023

I just upgraded to MacOs Sonoma 14.0 Beta (23A5286i). I've been running corelocationCli for many years, and usually when I upgrade OSs I have to reinstall it using Brew. However this time was different.

At first it actually worked just fine for a day. Then it stopped working, and I was getting "The operation couldn’t be completed. (kCLErrorDomain error 0.)" despite wifi being on.

In an attempt to fix the issue, I did my usual of running 'brew reinstall --cask corelocationcli' (so I have the latest version as of 7/18/2023)

Now I'm getting "Location services are disabled or location access denied. Please visit System Preferences > Security & Privacy > Privacy > Location Services"

However, Location services are on. But also, CoreLocationCLI is no longer in the list of things I can enable.

Thanks!

@lovelace
Copy link

lovelace commented Sep 9, 2023

I see the same issue on 13.5.1.
2023 MacBook Pro, M2Max

@kamidev
Copy link

kamidev commented Sep 10, 2023

Same issue on 13.5.2.
2023 M2 Max.

@bahman777
Copy link

This issue persists on 14.1.1 unfortunately - cannot get location.

@jeolsen
Copy link

jeolsen commented Dec 1, 2023

Same issue on 14.1.2

@PTac-h
Copy link

PTac-h commented Jan 3, 2024

same issue on macOS Sonoma 14.2.1

@PTac-h
Copy link

PTac-h commented Jan 4, 2024

Trying to compile source code didn't change anything.
I will try to follow this workaround and see if it does anything.

EDIT :

Impossible for me to replace the /var/db/locationd/clients.plist file (operation not permited even through a sudo su shell)
After getting into recovery mode to get a superuser shell, and replacing the file, it was automatically rolled back to original after a reboot.
Maybe did something wrong with my clients.plist file ?...

Anyway

I found a workaround using applescripting:

Implement core CLLocationManager module, ask for location rights, querry the location of the device once () and compile the script to an app with File > Export.
You now have your MyApp.app.
From there, run your app a first time, grant access to location, and from a terminal call /myapp.app/Contents/MacOS/applet to get your lat/long printed out

@FormalSnake
Copy link

Could you please provide me with the AppleScript?

@PTac-h
Copy link

PTac-h commented Mar 5, 2024

Could you please provide me with the AppleScript?

Sorry for the delayed response,
Here`s the apple script that I found here.

You need to export it with the App format, then launch it a first time as an app, and allow it to access your location.
From here, you can use the embedded script through your terminal (.../yourapp.app/Contents/MacOS/applet)

Note that it outputs your coordinates through an error that you can filter using regex.

use framework "CoreLocation"
use framework "Foundation"
use scripting additions

property this : a reference to the current application
property nil : a reference to missing value
property _1 : a reference to reference

property CLLocationManager : a reference to CLLocationManager of this
property kCLLocationAccuracyBest : a reference to 3000.0
--------------------------------------------------------------------------------
property running : false
property result : missing value -- Lat./long. or error description
property number : 0 -- Error code
property seconds : 10 -- Maximum time to allow script to run
--------------------------------------------------------------------------------
# IMPLEMENTATION:
my performSelectorOnMainThread:"getLocation" withObject:nil waitUntilDone:true
return my result
--------------------------------------------------------------------------------
# HANDLERS & SCRIPT OBJECTS:
to getLocation()
	set locationManager to CLLocationManager's new()
	
	locationManager's setDelegate:me
	locationManager's setDesiredAccuracy:kCLLocationAccuracyBest
	
	set my running to true
	set started to current date
	
	locationManager's startUpdatingLocation()
	
	repeat while my running
		delay 0.5
		if (current date) - started > my seconds then exit repeat
	end repeat
end getLocation

on locationManager:locationManager didUpdateLocations:locations
	local locationManager, locations
	
	locationManager's stopUpdatingLocation()
	
	set my running to false
	set my result to (locations's valueForKey:"coordinate") as record
	set coordinateText to "{" & quoted form of ("latitude:" & (my result's latitude) & ", longitude:" & (my result's longitude)) & "}"
	do shell script "echo " & coordinateText
	
end locationManager:didUpdateLocations:

on locationManager:locationManager didFailWithError:err
	local locationManager, err
	
	tell err's code()
		set my number to it
		set my result to item (it + 1) in my enum's kCLError
		set my running to false
	end tell
end locationManager:didFailWithError:

script enum
	property kCLError : {¬
		"Location Unknown", ¬
		"Denied", ¬
		"Network", ¬
		"Heading Failure", ¬
		"Region Monitoring Denied", ¬
		"Region Monitoring Failure", ¬
		"Region Monitoring Setup Delayed", ¬
		"Region Monitoring Response Delayed", ¬
		"Geocode Found No Result", ¬
		"Geocode Found Partial Result", ¬
		"Geocode Canceled", ¬
		"Deferred Failed", ¬
		"Deferred Not Updating Location", ¬
		"Deferred Accuracy Too Low", ¬
		"Deferred Distance Filtered", ¬
		"Deferred Canceled", ¬
		"Ranging Unavailable", ¬
		"Ranging Failure"}
	property CLAuthorizationStatus : {¬
		"Not Determined", ¬
		"Restricted", ¬
		"Denied", ¬
		"Authorized (Always)", ¬
		"Authorized When In Use"}
end script
---------------------------------------------------------------------------❮END❯
Capture d’écran 2024-03-05 à 22 04 57
@realityexpander
Copy link

I tried your script approach, and the best I can get after reviewing all your instructions is "Denied"

This seems like a major issue for Apple developers... is it even possible to get the Location from a CLI? Does there need to be a application server setup to accept and run in the background the only way to access the Location API now?

@Foxtrod89
Copy link

I tried your script approach, and the best I can get after reviewing all your instructions is "Denied"

This seems like a major issue for Apple developers... is it even possible to get the Location from a CLI? Does there need to be a application server setup to accept and run in the background the only way to access the Location API now?

Make sure you set keys Authorized, Whitelisted for /usr/local/Caskroom/corelocationcli/4.0.2/CoreLocationCLI record. With this danger in mind I finally made it work on my Sonoma 14.3.1, service isn't listed in location services though 🤔

@realityexpander
Copy link

Instead of hacking, I am suggesting that my users install this command-line accessible tool:

https://github.com/RhetTbull/locationator

@jbrepogmailcom
Copy link

Instead of hacking, I am suggesting that my users install this command-line accessible tool:

https://github.com/RhetTbull/locationator

Hi. And how do you set up location with your tool? My understanding it is just for quering various types of info from location API, but not for setting location.

@varenc
Copy link

varenc commented May 25, 2024

You need to export it with the App format, then launch it a first time as an app, and allow it to access your location.
From here, you can use the embedded script through your terminal (.../yourapp.app/Contents/MacOS/applet)

@PTac-h This script works great and taught me some things about AppleScript but I'm stuck on actually getting the location output in a useful format.

When I run that in the Script Editor I get the coordinates, and when I run the .app directly from Finder I can authorize the app and see that it works. I can run getLocation.app/Contents/MacOS/applet without a permission error... but the trouble is that running it in that way produces no output! I can't get any log "..." lines to appear in stdout/stderr when running the .app.

My current janky workaround is to just write the lat/lng to a file and read that..but that's non-ideal. How are you able to read the output directly from the packaged .app?

@bradleyCPA
Copy link

bradleyCPA commented Jul 8, 2024

Seems like you could also workaround with something like

diff --git a/Package.swift b/Package.swift
index 84485ed..d9698c0 100644
--- a/Package.swift
+++ b/Package.swift
@@ -12,6 +12,11 @@ let package = Package(
         .executable(name: "CoreLocationCLI", targets: ["CoreLocationCLI"])
     ],
     targets: [
-        .executableTarget(name: "CoreLocationCLI")
+        // Targets are the basic building blocks of a package, defining a module or a test suite.
+        // Targets can depend on other targets in this package and products from dependencies.
+        .executableTarget(
+            name: "CoreLocationCLI",
+            linkerSettings: [ .unsafeFlags( ["-Xlinker", "-sectcreate", "-Xlinker", "__TEXT", "-Xlinker", "__info_plist", "-Xlinker", "Resources/Info.plist"] ) ]
+       )
     ]
 )
diff --git a/Resources/Info.plist b/Resources/Info.plist
new file mode 100644
index 0000000..76cc2e2
--- /dev/null
+++ b/Resources/Info.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+        <key>CFBundleIdentifier</key>
+        <string>com.barf.CoreLocationCLI</string>
+        <key>CFBundleName</key>
+        <string>CoreLocationCLI</string>
+        <key>NSLocationUsageDescription</key>
+        <string>gimme cookie!</string>
+        <key>NSLocationWhenInUseUsageDescription</key>
+        <string>gimme cookie!</string>
+        <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+        <string>gimme cookie!</string>
+</dict>
+</plist>
diff --git a/Resources/entitlements.plist b/Resources/entitlements.plist
new file mode 100644
index 0000000..7e13092
--- /dev/null
+++ b/Resources/entitlements.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+    <dict>
+        <key>com.apple.security.personal-information.location</key>
+        <true/>
+    </dict>
+</plist>
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..fd7e8f4
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env sh
+
+rm -rf build
+mkdir build
+
+swift build --disable-sandbox
+
+mkdir -p build/CoreLocationCLI.app/Contents/MacOS
+
+cp Resources/Info.plist build/CoreLocationCLI.app/Contents
+cp .build/arm64-apple-macosx/debug/CoreLocationCLI build/CoreLocationCLI.app/Contents/MacOS
+# or do this in release mode to get a FAT binary
+# swift build --disable-sandbox -c release --arch arm64 --arch x86_64
+# mkdir -p build/CoreLocationCLI.app/Contents/MacOS
+# cp Resources/Info.plist build/CoreLocationCLI.app/Contents
+# cp .build/apple/Products/Release/CoreLocationCLI build/CoreLocationCLI.app/Contents/MacOS
+
+codesign --deep --force --verify --verbose --sign REPLACEME --options=runtime --entitlements Resources/entitlements.plist build/CoreLocationCLI.app

Using your own keys for signing. Edit the build script to copy whatever executable you want. Build using build.sh. Then running ./build/CoreLocationCLI.app/Contents/MacOS/CoreLocationCLI should populate the settings.app. Not sure if Package.swift has the concept of post build tasks so just used the shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet