Read pushes: ask mod_apush for them and withdraw a chat's notices on one #33

Closed
ann wants to merge 1 commit from feat/push-read-withdraw into master
Owner

The phone asks for read pushes and clears a chat's notifications when the chat is read on another device, as the Android app does.

  • push set_target for the APNs token now carries apushRead: "1" (the PushKit token, calls only, does not), so anotherim-server's mod_apush sends a read push when the chat was read or answered elsewhere and this phone has no live session.
  • apushd delivers it over APNs as a silent background push with the sealed summary (no apushKind in the clear on APNs). AppPushPayload reads kind: "read", or a message summary with an explicit count: 0 (anotherim-js docs/push.md, "Read elsewhere"), as .read(account:chat:).
  • AppDelegate gets a background-push handler that withdraws the chat's delivered notices by their thread (AppPushThread), the same thread the notification service extension files them under. A clear apushKind: read is honoured too.
  • project.yml adds the remote-notification background mode; without it iOS delivers no silent push to the app.

Tests: PushEnvelopeTests (read summary, count 0, read without a chat refused; apushRead only on the APNs token) and TackyAPITests' set_target frame. Built and run on an iOS 27 simulator: 36 tests, 0 failures. Not yet tried end to end on a device.

🤖 Generated with Claude Code

The phone asks for read pushes and clears a chat's notifications when the chat is read on another device, as the Android app does. - `push set_target` for the APNs token now carries `apushRead: "1"` (the PushKit token, calls only, does not), so anotherim-server's mod_apush sends a read push when the chat was read or answered elsewhere and this phone has no live session. - apushd delivers it over APNs as a silent `background` push with the sealed summary (no `apushKind` in the clear on APNs). `AppPushPayload` reads `kind: "read"`, or a message summary with an explicit `count: 0` (anotherim-js docs/push.md, "Read elsewhere"), as `.read(account:chat:)`. - `AppDelegate` gets a background-push handler that withdraws the chat's delivered notices by their thread (`AppPushThread`), the same thread the notification service extension files them under. A clear `apushKind: read` is honoured too. - `project.yml` adds the `remote-notification` background mode; without it iOS delivers no silent push to the app. Tests: PushEnvelopeTests (read summary, count 0, read without a chat refused; apushRead only on the APNs token) and TackyAPITests' set_target frame. Built and run on an iOS 27 simulator: 36 tests, 0 failures. Not yet tried end to end on a device. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The APNs token's push set_target now carries apushRead: "1" (the PushKit
token, calls only, does not), so anotherim-server's mod_apush sends a read
push when the chat was read or answered on another device and this phone's
session is gone. apushd delivers it over APNs as a silent background push
with the sealed summary; AppPushPayload reads `kind: "read"` (or a message
summary with an explicit `count: 0`, anotherim-js docs/push.md "Read
elsewhere") as .read(account:chat:), and AppDelegate's background-push
handler withdraws the chat's delivered notices by their thread
(AppPushThread), as the app does when the chat's read point moves. A clear
`apushKind: read` is honoured too should it ever come. project.yml adds the
remote-notification background mode, without which iOS delivers no silent
push. Tests: PushEnvelopeTests (read summary, count 0, read without a chat
refused; apushRead only on the APNs token), TackyAPITests' set_target frame.
Built and PushEnvelopeTests/TackyAPITests run on an iOS 27 simulator: 36
tests, 0 failures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor

Ported onto feat/ui-redesign in branch feat/push-read-withdraw-ui (fb7c264): https://dev.another.im/another-im/anotherim-swift/compare/feat/ui-redesign...feat/push-read-withdraw-ui — TestFlight builds come from feat/ui-redesign; master is 92 commits behind and has the old AppDelegate and push code. One difference: a kind: message summary with count: 0 stays a message (PushEnvelopeTests has pinned that since 8846f6a; it comes as an alert through the notification service extension). This PR is closed once the port's PR is open.

Ported onto `feat/ui-redesign` in branch `feat/push-read-withdraw-ui` (fb7c264): https://dev.another.im/another-im/anotherim-swift/compare/feat/ui-redesign...feat/push-read-withdraw-ui — TestFlight builds come from `feat/ui-redesign`; `master` is 92 commits behind and has the old AppDelegate and push code. One difference: a `kind: message` summary with `count: 0` stays a message (PushEnvelopeTests has pinned that since 8846f6a; it comes as an alert through the notification service extension). This PR is closed once the port's PR is open.
fmodf closed this pull request 2026-11-07 08:13:09 +00:00

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
done
fixed
returned
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
another-im/anotherim-swift!33
No description provided.