runtime
Package runtime is the Go API of the Drift location plugin (github.com/go-drift/drift/plugins/location/plugin in drift.yaml).
import location "github.com/go-drift/drift/plugins/location/runtime"
go func() {
status, err := location.Permission.WhenInUse.Request(ctx)
if err != nil || status != platform.PermissionGranted {
return
}
fix, err := location.Current(ctx, location.Options{HighAccuracy: true})
...
}()
Permission requests and the methods taking a ctx wait for the platform, so call them from a goroutine: from the UI thread they fail with platform.ErrBlocksUIThread. Updates is a stream; Listen from anywhere. The platform's updates run while it has listeners, with the options SetUpdateOptions set.
Background updates
A stream started with UpdateOptions.Background keeps delivering updates to Go while the app is in the background, for as long as the app's process lives. It needs the plugin's always: config and the Always permission, and must be started while the app is in the foreground (Android does not allow it from the background).
- iOS keeps the app running in the background while the stream is on, showing the blue location indicator in the status bar. Updates stop when the user force-quits the app (swipes it away in the app switcher) or the system terminates it, and the app is not relaunched for them.
- Android runs a foreground service with an ongoing notification (its text comes from the always: config), which keeps the process alive after the app leaves the screen and, on most devices, after the user swipes it away from Recents. Updates stop when the process is killed (force stop, the Task Manager's Stop, low memory) and do not restart.
Unsubscribing the last listener ends the stream, the service and the indicator.
Variables
var (
// ErrPermissionDenied indicates the app has no location permission:
// request Permission.WhenInUse first.
ErrPermissionDenied = errors.New("location permission not granted")
// ErrDisabled indicates the user turned location services off.
ErrDisabled = errors.New("location services are turned off")
// ErrUnavailable indicates no fix could be obtained.
ErrUnavailable = errors.New("no location fix available")
// ErrBackgroundNotConfigured indicates background updates were
// requested without the location plugin's always: config.
ErrBackgroundNotConfigured = errors.New("background location updates need the location plugin's always: config")
// ErrAlwaysDenied indicates background updates were requested without
// the Always permission: request Permission.Always first.
ErrAlwaysDenied = errors.New("background location updates need the Always location permission")
// ErrBackgroundStart indicates background updates were started while
// the app was in the background, which Android does not allow.
ErrBackgroundStart = errors.New("background location updates must start while the app is in the foreground")
)
Permission holds the location permissions.
var Permission = Permissions{
WhenInUse: platform.NewPermission("location"),
Always: alwaysPermission{platform.NewPermission("location_always")},
}
func IsEnabled
func IsEnabled(ctx context.Context) (bool, error)
IsEnabled reports whether location services are turned on. It waits for the platform, so call it from a goroutine.
func SetUpdateOptions
func SetUpdateOptions(opts UpdateOptions) error
SetUpdateOptions sets the options of the update stream, Updates: a running stream (one with listeners) changes at once, and the next one starts with them. Until the first call the stream uses high accuracy, in the foreground. It is one setting for the app, not per listener.
A failed call leaves the options and the running stream as they were. It fails with ErrBackgroundNotConfigured or ErrAlwaysDenied for Background without the always: config or the Always permission, and, when the stream is running but has lost access, with ErrPermissionDenied or ErrDisabled. A background stream must also start while the app is in the foreground (Android): with ErrBackgroundStart here when the stream is running, and on the Listen that starts it otherwise, through its OnError. Any goroutine may call it.
func Updates
func Updates() *platform.Stream[Update]
Updates streams locations. The platform's updates run while the stream has listeners: the first Listen starts them, with the options SetUpdateOptions set, and unsubscribing the last stops them, so a listener left subscribed keeps the GPS on.
A start that fails (no permission, ErrPermissionDenied; services off, ErrDisabled; ErrBackgroundStart), and a running stream that fails, such as the user revoking the permission (ErrPermissionDenied), reach the listeners' OnError; unsubscribe and listen again to retry.
type Options
Options configures location requests.
type Options struct {
// HighAccuracy requests the highest available accuracy (may use more power).
HighAccuracy bool
// DistanceFilter is the minimum distance in meters between updates.
DistanceFilter float64
// IntervalMs is the desired update interval in milliseconds (Android).
IntervalMs int64
// FastestIntervalMs is the fastest acceptable update interval in
// milliseconds (Android).
FastestIntervalMs int64
}
type Permissions
Permissions are the location permission levels.
type Permissions struct {
// WhenInUse is location access while the app is in use.
WhenInUse platform.Permission
// Always is location access at any time, including while the app is
// in the background, as background updates (UpdateOptions.Background)
// need. It needs the plugin's always: config; without it, its calls
// fail with platform.ErrPermissionNotRegistered. On iOS, WhenInUse
// must be granted first, and iOS asks once: after that, Always reads
// platform.PermissionPermanentlyDenied until granted in Settings. On
// Android, the user grants it in Settings.
Always platform.Permission
}
type Update
Update is one location reading.
type Update struct {
// Latitude is the latitude in degrees.
Latitude float64
// Longitude is the longitude in degrees.
Longitude float64
// Altitude is the altitude in meters.
Altitude float64
// Accuracy is the estimated horizontal accuracy in meters.
Accuracy float64
// Heading is the direction of travel in degrees.
Heading float64
// Speed is the speed in meters per second.
Speed float64
// Timestamp is when the reading was taken.
Timestamp time.Time
// IsMocked reports whether the reading came from a mock provider or
// a simulator.
IsMocked bool
}
func Current
func Current(ctx context.Context, opts Options) (Update, error)
Current returns a fresh location fix. It waits for the platform, so call it from a goroutine.
func LastKnown
func LastKnown(ctx context.Context) (*Update, error)
LastKnown returns the most recent cached fix without requesting a new one, or nil when there is none. It waits for the platform, so call it from a goroutine.
type UpdateOptions
UpdateOptions configures the stream of updates (SetUpdateOptions).
type UpdateOptions struct {
Options
// Background keeps updates coming while the app is in the background
// (see the package documentation). It needs the plugin's always:
// config (else ErrBackgroundNotConfigured) and the Always permission
// (else ErrAlwaysDenied), and must be started while the app is in the
// foreground (else ErrBackgroundStart, Android). On iOS it also keeps
// updates from pausing automatically while the device is stationary.
Background bool
}
Generated by gomarkdoc