app.location - Location Services API
Get the current geographic location, perform forward/reverse geocoding, and watch for location changes.
Permission: L2 sensitive, requires system Location Services permission. The system will prompt for authorization on first use.
Methods
app.location.isEnabled()
Check whether Location Services are enabled at the system level.
Returns: boolean
if not app.location.isEnabled() then
app.dialog.alert("Location Services", "Please enable Location Services in System Settings")
end
app.location.authorizationStatus()
Get the location authorization status for the app.
Returns: string
"authorized"- access has been granted"denied"- access has been denied"notDetermined"- authorization has not yet been requested"restricted"- access is restricted (e.g., parental controls)
local status = app.location.authorizationStatus()
if status == "denied" then
app.dialog.alert("Permission Required", "Please allow location access in System Settings")
end
app.location.current()
Get the current geographic location (synchronous, blocks until a location is obtained or times out).
Returns: table, error - location information:
latitude(number) - latitudelongitude(number) - longitudealtitude(number) - altitude in metersaccuracy(number) - horizontal accuracy in meterstimestamp(string) - timestamp (ISO 8601)
local loc, err = app.location.current()
if loc then
app.log.info(string.format("Location: %.6f, %.6f (accuracy: %.0fm)",
loc.latitude, loc.longitude, loc.accuracy))
else
app.log.error("Failed to get location: " .. (err or ""))
end
app.location.geocode(address)
Convert an address string to geographic coordinates (forward geocoding).
Parameters:
address(string) - address string
Returns: table, error - geographic information:
latitude(number) - latitudelongitude(number) - longitudename(string) - place namestreet(string) - streetcity(string) - citystate(string) - state/provincecountry(string) - countrycountryCode(string) - country code (e.g., “US”)postalCode(string) - postal code
local result, err = app.location.geocode("1 Infinite Loop, Cupertino, CA")
if result then
app.log.info(string.format("Coordinates: %.6f, %.6f", result.latitude, result.longitude))
app.log.info("City: " .. result.city)
end
app.location.reverseGeocode(lat, lon)
Convert coordinates to address information (reverse geocoding).
Parameters:
lat(number) - latitudelon(number) - longitude
Returns: table, error - geographic information (same fields as geocode() return value)
local loc = app.location.current()
if loc then
local addr, err = app.location.reverseGeocode(loc.latitude, loc.longitude)
if addr then
app.log.info("Current address: " .. (addr.street or "") .. ", " .. (addr.city or ""))
end
end
app.location.watch(event, callback)
Watch for location change events.
Parameters:
event(string) - event name (currently only"locationChanged"is supported)callback(function) - callback function, receives a location table:latitude(number) - latitudelongitude(number) - longitudealtitude(number) - altitude in metersaccuracy(number) - horizontal accuracy in meterstimestamp(string) - timestamp (ISO 8601)
Returns: string, error - watcher handle ID
local handle, err = app.location.watch("locationChanged", function(e)
app.log.info(string.format("Location updated: %.6f, %.6f", e.latitude, e.longitude))
end)
app.location.stopAllWatchers()
Stop all location watchers registered by the current plugin.
Returns: boolean
app.location.stopAllWatchers()
app.location.listWatchers()
List all location watchers registered by the current plugin.
Returns: array<table> - each item contains:
id(string) - watcher handle IDevent(string) - event name being watched
local watchers = app.location.listWatchers()
app.log.info("Active location watchers: " .. #watchers)
Description
- Location Services require explicit user authorization; after denial, the user must manually enable it in System Settings → Privacy & Security → Location Services
current()uses the CoreLocation framework internally, balancing accuracy with speed; accuracy may degrade indoorsgeocode()andreverseGeocode()rely on Apple Maps services and require a network connection- Watchers registered via
watch()are automatically cleaned up when the plugin is unloaded - Location permission is an L2 sensitive permission; plugins must declare
"permissions": ["location"]inplugin.json
Examples
Get Current Location and Display Address
function MyPlugin:handleGetLocation(context)
local status = app.location.authorizationStatus()
if status ~= "authorized" then
app.dialog.alert("Permission", "Location Services not authorized (status: " .. status .. ")")
return
end
app.progress.show("Locating", {message = "Getting current location..."})
local loc, err = app.location.current()
app.progress.hide()
if not loc then
app.dialog.alert("Error", "Failed to get location: " .. (err or ""))
return
end
local addr, _ = app.location.reverseGeocode(loc.latitude, loc.longitude)
local info = string.format(
"Coordinates: %.6f, %.6f\nAltitude: %.0f m\nAccuracy: %.0f m",
loc.latitude, loc.longitude, loc.altitude, loc.accuracy
)
if addr then
info = info .. "\n\nAddress: " .. (addr.street or "") ..
"\nCity: " .. (addr.city or "") ..
"\nCountry: " .. (addr.country or "")
end
app.dialog.alert("Current Location", info)
end
Tag Files with GPS Coordinates
function MyPlugin:handleTagWithLocation(context)
local loc, err = app.location.current()
if not loc then return end
for _, file in ipairs(context.selectedFiles) do
local coord = string.format("%.6f,%.6f", loc.latitude, loc.longitude)
app.xattr.set(file, "com.irightmenu.gps", coord)
end
app.notification.show("Done", "Tagged " .. #context.selectedFiles .. " files with location")
end