mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-25 00:20:45 +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 SwiftUI
|
||||||
import UserNotifications
|
import UserNotifications
|
||||||
|
|
||||||
|
extension UNNotification: @unchecked @retroactive Sendable {}
|
||||||
extension UNNotificationResponse: @unchecked @retroactive Sendable {}
|
extension UNNotificationResponse: @unchecked @retroactive Sendable {}
|
||||||
extension UNUserNotificationCenter: @unchecked @retroactive Sendable {}
|
extension UNUserNotificationCenter: @unchecked @retroactive Sendable {}
|
||||||
|
|
||||||
public struct PushAccount: Equatable {
|
public struct PushKeys: Sendable {
|
||||||
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 {
|
enum Constants {
|
||||||
static let endpoint = "https://icecubesrelay.fly.dev"
|
|
||||||
static let keychainAuthKey = "notifications_auth_key"
|
static let keychainAuthKey = "notifications_auth_key"
|
||||||
static let keychainPrivateKey = "notifications_private_key"
|
static let keychainPrivateKey = "notifications_private_key"
|
||||||
}
|
}
|
||||||
|
|
||||||
public static let shared = PushNotificationsService()
|
public init() { }
|
||||||
|
|
||||||
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 {
|
private var keychain: KeychainSwift {
|
||||||
let keychain = KeychainSwift()
|
let keychain = KeychainSwift()
|
||||||
#if !DEBUG && !targetEnvironment(simulator)
|
#if !DEBUG && !targetEnvironment(simulator)
|
||||||
|
@ -57,44 +27,7 @@ public struct HandledNotification: Equatable {
|
||||||
#endif
|
#endif
|
||||||
return keychain
|
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 {
|
public var notificationsPrivateKeyAsKey: P256.KeyAgreement.PrivateKey {
|
||||||
if let key = keychain.get(Constants.keychainPrivateKey),
|
if let key = keychain.get(Constants.keychainPrivateKey),
|
||||||
let data = Data(base64Encoded: key)
|
let data = Data(base64Encoded: key)
|
||||||
|
@ -130,7 +63,7 @@ public struct HandledNotification: Equatable {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func makeRandomNotificationsAuthKey() -> Data {
|
private static func makeRandomNotificationsAuthKey() -> Data {
|
||||||
let byteCount = 16
|
let byteCount = 16
|
||||||
var bytes = Data(count: byteCount)
|
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 {
|
extension PushNotificationsService: UNUserNotificationCenterDelegate {
|
||||||
public func userNotificationCenter(_: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
|
public func userNotificationCenter(_: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
|
||||||
guard let plaintext = response.notification.request.content.userInfo["plaintext"] as? Data,
|
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)
|
handledNotification = .init(account: account.account, notification: notification)
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func userNotificationCenter(_ center: UNUserNotificationCenter,
|
||||||
|
willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
|
||||||
|
return [.banner, .sound]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Data {
|
extension Data {
|
||||||
|
|
Loading…
Reference in a new issue