pEp macOS Desktop adapter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

148 lines
5.3 KiB

//
// DownloadNotificationManager.swift
// pp updates
//
// Created by David Alarcon on 27/11/20.
// Copyright © 2020 pp foundation. All rights reserved.
//
import UserNotifications
fileprivate struct DownloadNotification {
var id: String
var product: Product
}
public protocol DownloadNotificationManagerDelegate: class {
func installSelected(with product: Product)
func notNowSelected()
}
extension DownloadNotificationManagerDelegate {
func notNowSelected() { }
}
@available(OSX 10.14, *)
public class DownloadNotificationManager: NSObject {
public weak var delegate: DownloadNotificationManagerDelegate?
private var notifications = [DownloadNotification]()
private lazy var notificationCenter = UNUserNotificationCenter.current()
override init() {
super.init()
notificationCenter.removeDeliveredNotifications(withIdentifiers: ["p≡p updates"])
notificationCenter.delegate = self
setupNotificationCategories()
}
public func addDownloadNotification(with product: Product) -> Void {
notifications.append(DownloadNotification(id: UUID().uuidString, product: product))
}
public func scheduleDownloadNotifications() {
notificationCenter.getNotificationSettings { settings in
switch settings.authorizationStatus {
case .notDetermined:
self.requestNotificationAuthorization()
case .authorized, .provisional:
self.scheduleNotifications()
default:
break
}
}
}
public func scheduleDownloadNotification(with product: Product) {
addDownloadNotification(with: product)
scheduleDownloadNotifications()
}
}
// MARK: - Private
@available(OSX 10.14, *)
extension DownloadNotificationManager {
private func requestNotificationAuthorization() -> Void {
notificationCenter
.requestAuthorization(options: [.alert, .badge, .alert]) { [weak self] granted, error in
guard let me = self else {
return
}
guard granted else {
if let error = error {
print("pEpNotifications[Error]: ", error)
}
return
}
me.scheduleNotifications()
}
}
private func setupNotificationCategories() {
let installAction = UNNotificationAction(identifier: "installAction", title: NSLocalizedString("Install", comment: ""), options: .init(rawValue: 0))
let notNowAction = UNNotificationAction(identifier: "notNowAction", title: NSLocalizedString("Not now", comment: ""), options: .init(rawValue: 0))
let category = UNNotificationCategory(identifier: "p≡p",
actions: [installAction, notNowAction],
intentIdentifiers: [],
hiddenPreviewsBodyPlaceholder: "",
options: .customDismissAction)
self.notificationCenter.setNotificationCategories([category])
}
private func scheduleNotifications() -> Void {
notifications.forEach { notification in
sendNotification(with: notification)
}
}
private func sendNotification(with notification: DownloadNotification) {
guard let name = notification.product["name"] as? String else {
return
}
let notificationContent = UNMutableNotificationContent()
notificationContent.title = NSLocalizedString("Update available", comment: "")
notificationContent.body = String(format: NSLocalizedString("A new update for %@ is ready to be installed.", comment: ""), name)
notificationContent.sound = UNNotificationSound.default
notificationContent.categoryIdentifier = "p≡p"
notificationContent.userInfo = notification.product
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: Double.leastNonzeroMagnitude,
repeats: false)
let request = UNNotificationRequest(identifier: "p≡p updates",
content: notificationContent,
trigger: trigger)
notificationCenter.add(request) { error in
if let error = error {
print("pEpNotifications[Error]: ", error)
}
}
}
}
// MARK: - UNUserNotificationCenterDelegate
@available(OSX 10.14, *)
extension DownloadNotificationManager: UNUserNotificationCenterDelegate {
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
switch response.actionIdentifier {
case "installAction":
if let product = response.notification.request.content.userInfo as? Product {
delegate?.installSelected(with: product)
}
case "notNowAction":
delegate?.notNowSelected()
default:
break
}
}
}