Calculating longitude and latitude

This branches off the “cleaner date formatting” thread…

It’s a bit complicated. A script needs permission, location services needs to be turned on, the script needs to be run on the main thread, and it’s asynchronous, so you need to send the message and get a reply in another handler.

But this should give you something to play with:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "CoreLocation" -- for location

if not current application's CLLocationManager's locationServicesEnabled() as boolean then
	error "Location Services not enabled"
end if
if current application's NSThread's isMainThread() as boolean then
	my startSearching()
	my performSelectorOnMainThread:"startSearching" withObject:(missing value) waitUntilDone:true
end if

on startSearching()
	set locationManager to current application's CLLocationManager's alloc()'s init()
	locationManager's setDelegate:me
	locationManager's setDesiredAccuracy:(current application's kCLLocationAccuracyThreeKilometers)
	locationManager's startUpdatingLocation()
end startSearching

on locationManager:locationManager didUpdateLocations:newLocations
	locationManager's stopUpdatingLocation()
	set newLocation to newLocations's lastObject()
	set theCoordinates to newLocation's coordinate()
		-- struct is passed as record in 10.11+
		set coords to ((latitude of theCoordinates) as text) & ", " & longitude of theCoordinates
	on error -- pre-10.10 we have to parse the description
		set theDescription to current application's NSString's stringWithString:(newLocation's |description|())
		set anNSScanner to current application's NSScanner's scannerWithString:theDescription
		anNSScanner's setCharactersToBeSkipped:(current application's NSCharacterSet's characterSetWithCharactersInString:"<,")
		set {theResult, aLat} to anNSScanner's scanDouble:(reference)
		set {theResult, aLng} to anNSScanner's scanDouble:(reference)
		set coords to (aLat as text) & ", " & aLng
	end try
	display dialog coords
end locationManager:didUpdateLocations:

on locationManager:anCLLocationManager didFailWithError:anNSError
	error (anNSError's localizedDescription() as text)
end locationManager:didFailWithError:


Thanks Shane

Just a problem : I am able to force the script to run in the main thread in Apple’s Script Editor or in your ASObjC Explorer but I don’t know how to do that in Script Debugger.

Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) mercredi 14 décembre 2016 17:07:45

You don’t need to here. The use of performSelectorOnMainThread::: solves the problem for you.

Hi all! Hi Shane!
Just by curiosity I ran your script but nothing appears. (Localisation Service enabled). Yosemite 10.10.5.
What could be the prob? Any idea?


Is WiFi enabled during your tests ?

I forgot to enable it for my first attempt and for sure, like you, I got no result.

Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) jeudi 15 décembre 2016 10:16:55

Did you follow Yvan’s advice?

Hi Shane.

When I tried it, I found that if I enabled Location Services AND gave Script Debugger permission to use them AND used a wi-fi connection instead of Ethernet between the computer and router, then the script would either work (display the dialog) or not. More often not. The first time it did work, it displayed three dialogs simultaneously, which could only be dismissed by force-quitting Script Debugger. Possibly these were due to previously failed runs suddenly being able to report back.

Interesting code though.

By the way, if the comments are correct, the first line of the script makes the ‘on error’ section unnecessary.

I suspect your diagnosis is correct. I had to quit SD several times while writing/testing it because of similar behavior. The other thing is that it can be quite slow initially (it then caches stuff), and if you give up and try again, you can cause confusion.

It could be a lot more robust, although there are limitations with ASObjC and having to use performSelectorOnMainThread:::.

Oops. Should be 10.11. Thanks, I’ll change it.