gitbay/Push/PushTarget.swift

v1.6.1
gitbay-ios/gitbay/Push/PushTarget.swift history · blame · raw

31 lines · 1600 bytes

 1import Foundation
 2
 3/// A tapped notification resolved against the accounts signed in on
 4/// this device: which account it belongs to, and the screen it opens.
 5nonisolated struct PushTarget: Equatable, Sendable {
 6    let accountID: String
 7    let destination: NotificationDestination
 8
 9    /// Nil when no signed-in account matches — you signed out of it —
10    /// or when the path names nothing the app can route to.
11    init?(payload: PushPayload, accounts: [Account]) {
12        guard let destination = notificationDestination(forPath: payload.path) else { return nil }
13        // Run the payload's instance through the same normalisation an
14        // account's did (trailing slash, default port) rather than
15        // comparing raw URLs, which a server's unnormalised config can
16        // make unequal even when they name the same instance.
17        guard let instance = try? GitbayInstance(url: payload.instance.absoluteString) else { return nil }
18        // Both sides, not just the payload's: an account stored before
19        // the constructor folded the default port still holds an
20        // explicit ":443". Normalising is for the comparison only —
21        // rewriting what is stored would change `Account.id` and orphan
22        // the Keychain token it keys.
23        let match = accounts.first {
24            $0.username == payload.user
25                && (try? GitbayInstance(url: $0.instance.baseURL.absoluteString))?.baseURL == instance.baseURL
26        }
27        guard let match else { return nil }
28        self.accountID = match.id
29        self.destination = destination
30    }
31}