2 months ago
bc722c7* Resolve review findings from #35
- Fetch the FX table on a private cacheless URLSession. The provider serves
it `Cache-Control: public, max-age=…`, so `URLSession.shared` left a second
copy in the on-disk `URLCache` that `setEnabled(false)` never deleted —
the consent sheet promises turning it off deletes the cached rates.
- `refreshNow()` returns whether a table landed, so "Update Now" reports a
failed fetch instead of springing back with the status line unchanged.
- `start()` replaces a live pump rather than bailing on `pump == nil`, so a
loop that already exited can't block every later restart.
- Clamp the snapshot age: a `fetchedAt` in the future (clock skew, an edited
cache) parked the refresh loop for longer than one interval.
- `CalcFormatter.currency` prints a clean "0.00" below ~1e-9 — a tiny
negative rendered as "-0.00".
- Drop the generated `rights` → XDR alias: the noun heuristic takes a name's
last word, and "Special Drawing Rights" isn't a "rights".
- Match the value line's `minimumScaleFactor` on the card badge so long
currency names ("Bosnia-Herzegovina Convertible Mark") shrink before they
ellipsize.
* Refresh rates daily, and trim the currency settings UI
- 6h -> 24h. The feed republishes about once a day, so the tighter interval
spent requests without returning newer numbers. Age is still measured from
the persisted `fetchedAt`, so a cold start with a same-day cache makes no
request at all and relaunching never re-fetches.
- Fold the standalone callout into the Currency Conversion row. The only
thing it really had to say off-state — nothing is contacted until you
enable it — now rides on the row's own subtitle, and the provider and
last-updated stamp ride on the Exchange Rates row.
- Cut the consent sheet from four bulleted points to one short paragraph
covering who, how often, what is sent and how to undo. `ConsentPoint`
goes with it.Parent246ce28