mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-24 08:00:38 +00:00
Fixes
This commit is contained in:
parent
b56ed36f17
commit
a184351cf3
1 changed files with 95 additions and 74 deletions
|
@ -8,48 +8,18 @@ import Observation
|
|||
import SwiftUI
|
||||
import UserNotifications
|
||||
|
||||
extension UNNotification: @unchecked @retroactive Sendable {}
|
||||
extension UNNotificationResponse: @unchecked @retroactive Sendable {}
|
||||
extension UNUserNotificationCenter: @unchecked @retroactive Sendable {}
|
||||
|
||||
public struct PushAccount: Equatable {
|
||||
public let server: String
|
||||
public let token: OauthToken
|
||||
public let accountName: String?
|
||||
|
||||
public init(server: String, token: OauthToken, accountName: String?) {
|
||||
self.server = server
|
||||
self.token = token
|
||||
self.accountName = accountName
|
||||
}
|
||||
}
|
||||
|
||||
public struct HandledNotification: Equatable {
|
||||
public let account: PushAccount
|
||||
public let notification: Models.Notification
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Observable public class PushNotificationsService: NSObject {
|
||||
public struct PushKeys: Sendable {
|
||||
enum Constants {
|
||||
static let endpoint = "https://icecubesrelay.fly.dev"
|
||||
static let keychainAuthKey = "notifications_auth_key"
|
||||
static let keychainPrivateKey = "notifications_private_key"
|
||||
}
|
||||
|
||||
public static let shared = PushNotificationsService()
|
||||
|
||||
public private(set) var subscriptions: [PushNotificationSubscriptionSettings] = []
|
||||
|
||||
public var pushToken: Data?
|
||||
|
||||
public var handledNotification: HandledNotification?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
}
|
||||
|
||||
|
||||
public init() { }
|
||||
|
||||
private var keychain: KeychainSwift {
|
||||
let keychain = KeychainSwift()
|
||||
#if !DEBUG && !targetEnvironment(simulator)
|
||||
|
@ -57,44 +27,7 @@ public struct HandledNotification: Equatable {
|
|||
#endif
|
||||
return keychain
|
||||
}
|
||||
|
||||
public func requestPushNotifications() {
|
||||
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { _, _ in
|
||||
DispatchQueue.main.async {
|
||||
UIApplication.shared.registerForRemoteNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func setAccounts(accounts: [PushAccount]) {
|
||||
subscriptions = []
|
||||
for account in accounts {
|
||||
let sub = PushNotificationSubscriptionSettings(account: account,
|
||||
key: notificationsPrivateKeyAsKey.publicKey.x963Representation,
|
||||
authKey: notificationsAuthKeyAsKey,
|
||||
pushToken: pushToken)
|
||||
subscriptions.append(sub)
|
||||
}
|
||||
}
|
||||
|
||||
public func updateSubscriptions(forceCreate: Bool) async {
|
||||
for subscription in subscriptions {
|
||||
await withTaskGroup(of: Void.self, body: { group in
|
||||
group.addTask {
|
||||
await subscription.fetchSubscription()
|
||||
if await subscription.subscription != nil, !forceCreate {
|
||||
await subscription.deleteSubscription()
|
||||
await subscription.updateSubscription()
|
||||
} else if forceCreate {
|
||||
await subscription.updateSubscription()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Key management
|
||||
|
||||
|
||||
public var notificationsPrivateKeyAsKey: P256.KeyAgreement.PrivateKey {
|
||||
if let key = keychain.get(Constants.keychainPrivateKey),
|
||||
let data = Data(base64Encoded: key)
|
||||
|
@ -130,7 +63,7 @@ public struct HandledNotification: Equatable {
|
|||
return key
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static func makeRandomNotificationsAuthKey() -> Data {
|
||||
let byteCount = 16
|
||||
var bytes = Data(count: byteCount)
|
||||
|
@ -139,6 +72,89 @@ public struct HandledNotification: Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
public struct PushAccount: Equatable {
|
||||
public let server: String
|
||||
public let token: OauthToken
|
||||
public let accountName: String?
|
||||
|
||||
public init(server: String, token: OauthToken, accountName: String?) {
|
||||
self.server = server
|
||||
self.token = token
|
||||
self.accountName = accountName
|
||||
}
|
||||
}
|
||||
|
||||
public struct HandledNotification: Equatable {
|
||||
public let account: PushAccount
|
||||
public let notification: Models.Notification
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Observable public class PushNotificationsService: NSObject {
|
||||
enum Constants {
|
||||
static let endpoint = "https://icecubesrelay.fly.dev"
|
||||
}
|
||||
|
||||
public static let shared = PushNotificationsService()
|
||||
|
||||
private let pushKeys = PushKeys()
|
||||
|
||||
public private(set) var subscriptions: [PushNotificationSubscriptionSettings] = []
|
||||
|
||||
public var pushToken: Data?
|
||||
|
||||
public var handledNotification: HandledNotification?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
}
|
||||
|
||||
private var keychain: KeychainSwift {
|
||||
let keychain = KeychainSwift()
|
||||
#if !DEBUG && !targetEnvironment(simulator)
|
||||
keychain.accessGroup = AppInfo.keychainGroup
|
||||
#endif
|
||||
return keychain
|
||||
}
|
||||
|
||||
public func requestPushNotifications() {
|
||||
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { _, _ in
|
||||
DispatchQueue.main.async {
|
||||
UIApplication.shared.registerForRemoteNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func setAccounts(accounts: [PushAccount]) {
|
||||
subscriptions = []
|
||||
for account in accounts {
|
||||
let sub = PushNotificationSubscriptionSettings(account: account,
|
||||
key: pushKeys.notificationsPrivateKeyAsKey.publicKey.x963Representation,
|
||||
authKey: pushKeys.notificationsAuthKeyAsKey,
|
||||
pushToken: pushToken)
|
||||
subscriptions.append(sub)
|
||||
}
|
||||
}
|
||||
|
||||
public func updateSubscriptions(forceCreate: Bool) async {
|
||||
for subscription in subscriptions {
|
||||
await withTaskGroup(of: Void.self, body: { group in
|
||||
group.addTask {
|
||||
await subscription.fetchSubscription()
|
||||
if await subscription.subscription != nil, !forceCreate {
|
||||
await subscription.deleteSubscription()
|
||||
await subscription.updateSubscription()
|
||||
} else if forceCreate {
|
||||
await subscription.updateSubscription()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PushNotificationsService: UNUserNotificationCenterDelegate {
|
||||
public func userNotificationCenter(_: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
|
||||
guard let plaintext = response.notification.request.content.userInfo["plaintext"] as? Data,
|
||||
|
@ -154,6 +170,11 @@ extension PushNotificationsService: UNUserNotificationCenterDelegate {
|
|||
handledNotification = .init(account: account.account, notification: notification)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
public func userNotificationCenter(_ center: UNUserNotificationCenter,
|
||||
willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
|
||||
return [.banner, .sound]
|
||||
}
|
||||
}
|
||||
|
||||
extension Data {
|
||||
|
|
Loading…
Reference in a new issue