Skip to content

feat: location-based reminders (geofence arrive/leave triggers) #47

@BRO3886

Description

@BRO3886

Summary

Add support for location-based reminders (geofence triggers) — arrive/leave alerts tied to a geographic coordinate. This is a real feature in Reminders.app that rem currently can't express.

EventKit Public API

Location reminders are fully supported by the public EventKit API — no private ReminderKit bridge needed for core functionality:

  • EKStructuredLocation — holds title, geoLocation (CLLocation), and radius (meters)
  • EKAlarm.structuredLocation — attach a structured location to any alarm
  • EKAlarm.proximityEKAlarmProximityEnter (arrive) or EKAlarmProximityLeave (depart)
EKStructuredLocation *loc = [EKStructuredLocation locationWithTitle:@"Grocery Store"];
loc.geoLocation = [[CLLocation alloc] initWithLatitude:37.3318 longitude:-122.0312];
loc.radius = 200.0; // meters; 0 = system default

EKAlarm *alarm = [[EKAlarm alloc] init];
alarm.structuredLocation = loc;
alarm.proximity = EKAlarmProximityEnter;
[reminder addAlarm:alarm];

Private ReminderKit extras (optional, not required)

From issue #27's exploration:

  • REMAlarmVehicleTrigger — trigger on CarPlay vehicle arrival/departure (no public API equivalent)
  • REMStructuredLocation — richer than EKStructuredLocation (has address, routing, mapKitHandle)
  • REMAlarmContactTrigger — trigger when messaging a contact

Only vehicle triggers are unique to the private API. Standard geofence arrive/leave works entirely through public EventKit.

Implementation plan

go-eventkit (library layer)

  1. Add Location *AlarmLocation to the Alarm struct
  2. New AlarmLocation struct: Title, Latitude, Longitude, Radius, Proximity (arrive/leave/none)
  3. In bridge_darwin.m: read/write alarm.structuredLocation and alarm.proximity
  4. Add -framework CoreLocation to LDFLAGS (new framework dependency for CLLocation)
  5. Wire through CreateReminderInput and UpdateReminderInput

rem (CLI layer)

  • rem add --location "37.33,-122.03" --on-arrive or --on-leave
  • rem show displays location info when present
  • rem list --has-location filter (nice-to-have)
  • rem update --location to add/change/remove location trigger
  • Export/import roundtrip for location data

UX considerations

  • Coordinate input: raw lat,lng is not ergonomic but is the simplest path. Geocoding (address → coordinates) would need CLGeocoder which is async and requires network — adds meaningful complexity
  • Radius: default to system minimum (0), allow --radius 200 override in meters
  • Proximity: --on-arrive (default) and --on-leave flags, similar to how --remind-me works for time-based alarms

Permissions & testing

  • Location-based reminders require Location Services permission in addition to Reminders — second TCC prompt on macOS
  • Geofences only fire on physical device movement — not testable in headless/CI environments
  • Unit tests can verify struct serialization; integration tests limited to create/read (can't trigger the geofence)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions