crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit efcfef1c9534c0ede1b6fc9fe8d0e472083d17e7
parent 4ed262e195b17e4a66a060ca1bda724a4fccc50c
Author: Michael Camilleri <[email protected]>
Date:   Wed, 27 May 2026 11:41:07 +0900

Add push notification logging

Diffstat:
MCrossmate/Services/AppServices.swift | 54+++++++++++++++++++++++++++++++++++++++++-------------
MCrossmate/Services/PushClient.swift | 4+++-
2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/Crossmate/Services/AppServices.swift b/Crossmate/Services/AppServices.swift @@ -606,11 +606,19 @@ final class AppServices { /// ping — the user-facing event is "started playing", not "joined". func publishSessionStartPush(gameID: UUID) async { localSessionTracker.begin(gameID: gameID) - guard let pushClient, - let localAuthorID = identity.currentID, !localAuthorID.isEmpty - else { return } + guard let pushClient else { + syncMonitor.note("push(play): skipped (no pushClient)") + return + } + guard let localAuthorID = identity.currentID, !localAuthorID.isEmpty else { + syncMonitor.note("push(play): skipped (no authorID)") + return + } let lookup = recipientsAndTitle(forGameID: gameID, excluding: localAuthorID) - guard !lookup.recipients.isEmpty else { return } + guard !lookup.recipients.isEmpty else { + syncMonitor.note("push(play): skipped (no recipients)") + return + } let playerName = preferences.name.isEmpty ? "A player" : preferences.name let puzzleSuffix = lookup.title.isEmpty ? "the puzzle" : "the puzzle '\(lookup.title)'" await pushClient.publish( @@ -631,12 +639,23 @@ final class AppServices { /// permanently leaving the game. func publishSessionEndPush(gameID: UUID) async { let counts = localSessionTracker.consume(gameID: gameID) - guard counts.added > 0 || counts.cleared > 0 else { return } - guard let pushClient, - let localAuthorID = identity.currentID, !localAuthorID.isEmpty - else { return } + guard counts.added > 0 || counts.cleared > 0 else { + syncMonitor.note("push(pause): skipped (no edits)") + return + } + guard let pushClient else { + syncMonitor.note("push(pause): skipped (no pushClient)") + return + } + guard let localAuthorID = identity.currentID, !localAuthorID.isEmpty else { + syncMonitor.note("push(pause): skipped (no authorID)") + return + } let lookup = recipientsAndTitle(forGameID: gameID, excluding: localAuthorID) - guard !lookup.recipients.isEmpty else { return } + guard !lookup.recipients.isEmpty else { + syncMonitor.note("push(pause): skipped (no recipients)") + return + } let playerName = preferences.name.isEmpty ? "A player" : preferences.name let puzzleSuffix = lookup.title.isEmpty ? "the puzzle" : "the puzzle '\(lookup.title)'" var parts: [String] = [] @@ -657,11 +676,20 @@ final class AppServices { } private func publishCompletionPush(gameID: UUID, resigned: Bool) async { - guard let pushClient, - let localAuthorID = identity.currentID, !localAuthorID.isEmpty - else { return } + let kindLabel = resigned ? "resign" : "win" + guard let pushClient else { + syncMonitor.note("push(\(kindLabel)): skipped (no pushClient)") + return + } + guard let localAuthorID = identity.currentID, !localAuthorID.isEmpty else { + syncMonitor.note("push(\(kindLabel)): skipped (no authorID)") + return + } let lookup = recipientsAndTitle(forGameID: gameID, excluding: localAuthorID) - guard !lookup.recipients.isEmpty else { return } + guard !lookup.recipients.isEmpty else { + syncMonitor.note("push(\(kindLabel)): skipped (no recipients)") + return + } let playerName = preferences.name.isEmpty ? "A player" : preferences.name let puzzleSuffix = lookup.title.isEmpty ? "the puzzle" : "the puzzle '\(lookup.title)'" let kind: String diff --git a/Crossmate/Services/PushClient.swift b/Crossmate/Services/PushClient.swift @@ -105,6 +105,7 @@ final class PushClient { body: String ) async { guard !addressees.isEmpty else { return } + log("push(\(kind)): publishing to \(addressees.count) addressee(s)") let payload: [String: Any] = [ "kind": kind, "gameID": gameID.uuidString, @@ -122,8 +123,9 @@ final class PushClient { guard let http = response as? HTTPURLResponse, http.statusCode == 200 else { throw URLError(.badServerResponse) } + log("push(\(kind)): worker accepted") } catch { - log("Push publish (\(kind)) failed: \(error.localizedDescription)") + log("push(\(kind)) failed: \(error.localizedDescription)") } }