ReviewOS

craft-native/craft

fix(location): craft.watchPosition and clearWatch mean different things on each platform, and v1 can leave a dead watch

#220
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Three location watch surfaces sit side by side, and the page contract depends on which one a page reaches for, and on which platform.

calliOSAndroidcraft.d.ts
craft.watchPosition(cb)returns whatever craft.geolocation.watchPosition(cb) returns: a promise of true since #207, undefined beforethe same function as craft.location.watchPosition, returns a numeric id (-1 when there is no permission or no Play Services, and the callback is kept and never called)string
craft.clearWatch(id)ignores id and stops the native stream for every subscriberclears only that id(watchId: string) => void
craft.location.watchPosition(cb)numeric idnumeric idvia the SDK, number

Problems

  1. The flat pair disagrees across platforms and with its type. string is right on neither platform.
  2. craft.location.watchPosition on iOS can leave a dead watch. It calls void craft._invoke('watchPosition') only when its map goes from empty to one entry (CraftApp.swift, the v1 craft.location block). If that call rejects, for example with CAPABILITY_DISABLED or with Zig's PERMISSION_DENIED when the plist key is missing, the callback stays in the map. Every later subscriber is added without asking native again, so none of them ever fires, and the rejection is unhandled.
  3. Legacy and v1 share one native stream on iOS. craft.geolocation.clearWatch() stops updates under v1 subscribers, and v1 never restarts them, because its map is still non-empty.
  4. The legacy craft.geolocation.watchPosition listener is never removed, including when the call is refused.

Suggested direction

Make the flat pair delegate to craft.location on iOS, as Android already does, and type it number. When the v1 _invoke rejects, drop the entries it added so the next subscribe asks native again. Keep craft.geolocation.* for compatibility, but stop it from sharing clear semantics with v1.

This is a behaviour change for iOS pages that call craft.clearWatch() with no argument, which today stops everything, so it was kept out of #207.

Found while fixing #207.

Sign in to comment on this issue.