//
|
|
// DownloadNotificationManager.swift
|
|
// p≡p updates
|
|
//
|
|
// Created by David Alarcon on 27/11/20.
|
|
// Copyright © 2020 p≡p 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
|
|
}
|
|
|
|
}
|
|
}
|