An API client for ipx, and its event stream #1
Notifications
Due Date
No due date set.
Blocks
#2 A native player bar, and the Glass look it sits in
rays/ipodderx-app
#3 A native feed list and item list
rays/ipodderx-app
Reference: rays/ipodderx-app#1
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Everything native needs the same thing first: a typed client for ipx's HTTP API, and a reader for its event stream.
ipx already answers everything a client could want and needs no server change. The routes that matter here are GET /api/feeds, GET /api/entries and GET /api/feeds/{id}/entries (paged, with filter, q, sort and dir), POST /api/entries/{feed}/{guid}/flags and .../position, POST /api/read-all and /api/feeds/{id}/read-all, POST /api/enclosures/{id}/download and DELETE /api/enclosures/{id}, POST /api/fetch, and GET /media/{id}, which supports Range.
GET /api/events is server-sent events, the same broadcast the control socket carries: feed_start, feed_done, progress, download_done, reaped, scan_done and the rest. URLSession's bytes(for:) reads it without another dependency. Progress carries the enclosure id, without which a UI cannot tell one download from another.
Authentication is the web view's: ipx decides who is asking by cookie, and CookieBridge already keeps HTTPCookieStorage in step. The client sends nothing of its own.
This is worth doing whatever happens to the rest. A CarPlay browse tree is built from exactly these calls, so none of it is wasted even if the interface stays a web view.
Sources/Library.swift is the seed: it already does position, read and artwork.
Done in
f88ae65.Sources/API.swiftis the client: feeds, entries with the server's own paging, filtering, sorting and search, read and pinned, position, read-all, download, delete, fetch, and artwork.Sources/APIModels.swiftis what ipx sends, with the server's field names kept so a type here can be checked againstweb.rswithout translating first. It sends nothing of its own to authenticate — ipx decides who is asking by cookie andCookieBridgekeepsHTTPCookieStoragein step.Sources/Events.swiftreads/api/eventswith URLSession's byte stream, so no new dependency. An event this build has never heard of decodes as.otherrather than throwing: a new one on the server must not stop the stream. It reconnects with a backoff, since a deploy closes the stream cleanly and a daemon that is down should not be hammered.Library.swiftis gone, folded in. Two clients writing positions was one too many, and the page's forwarded beacon no longer carries a path — it asks the host to save and the host uses its own clock, the only one that is not stale when the web view has been frozen.Thirteen tests pass against the browser suite's fixture daemon rather than canned JSON, because the shapes are the server's and a fixture would only prove it matches itself. That includes a live scan reported over SSE, and the playback round trip, which still works after the move.