Current section

Files

Jump to
mob lib mob location.ex
Raw

lib/mob/location.ex

defmodule Mob.Location do
@moduledoc """
Device location (GPS / network).
Requires `:location` permission (request via `Mob.Permissions.request/2`).
iOS additionally needs `NSLocationWhenInUseUsageDescription` in
`Info.plist`; Android needs `ACCESS_FINE_LOCATION` and/or
`ACCESS_COARSE_LOCATION` in `AndroidManifest.xml`. See the
[permissions guide](permissions.html) for the cross-platform table
and the "the dialog never appears" failure mode — a missing plist
key or manifest entry is the single most common reason this module
silently does nothing.
Location updates arrive as:
handle_info({:location, %{lat: lat, lon: lon, accuracy: acc, altitude: alt}}, socket)
handle_info({:location, :error, reason}, socket)
Common `reason` atoms:
* `:permission_denied` — user denied `:location` (or revoked it
mid-session via Settings). iOS surfaces this through
`locationManagerDidChangeAuthorization:`; Android via the
permission flow.
* `:unavailable` — the OS can't get a fix right now
(`CLLocationManager.didFailWithError`).
iOS: `CLLocationManager`. Android: `FusedLocationProviderClient`.
"""
@type accuracy :: :high | :balanced | :low
@doc """
Request a single location fix, then stop.
"""
@spec get_once(Mob.Socket.t()) :: Mob.Socket.t()
def get_once(socket) do
:mob_nif.location_get_once()
socket
end
@doc """
Start continuous location updates.
Options:
- `accuracy: :high | :balanced | :low` (default `:balanced`)
Call `stop/1` when done to save battery.
"""
@spec start(Mob.Socket.t(), keyword()) :: Mob.Socket.t()
def start(socket, opts \\ []) do
accuracy = Keyword.get(opts, :accuracy, :balanced)
:mob_nif.location_start(accuracy)
socket
end
@doc """
Stop continuous location updates.
"""
@spec stop(Mob.Socket.t()) :: Mob.Socket.t()
def stop(socket) do
:mob_nif.location_stop()
socket
end
end