Browse Source

MOS-10 Create DownloadNotificationManager for os version from 10.14.

MOS-10
David Alarcon 2 years ago
parent
commit
7f4eeaca0e
4 changed files with 203 additions and 18 deletions
  1. +4
    -0
      Submodules/pEpNotifications/pEpNotifications.xcodeproj/project.pbxproj
  2. +50
    -17
      Submodules/pEpNotifications/pEpNotifications/AppDelegate.swift
  3. +148
    -0
      Submodules/pEpNotifications/pEpNotifications/DownloadNotificationManager.swift
  4. +1
    -1
      Submodules/pEpNotifications/pEpNotifications/DownloadStateNotifier.swift

+ 4
- 0
Submodules/pEpNotifications/pEpNotifications.xcodeproj/project.pbxproj View File

@ -12,6 +12,7 @@
3527B2B924802F87007A6276 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3527B2B824802F87007A6276 /* Preview Assets.xcassets */; };
3594303F2483011000DCBD65 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3594303D2483011000DCBD65 /* Main.storyboard */; };
359430482483264F00DCBD65 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3594304A2483264F00DCBD65 /* Localizable.strings */; };
4E0FD9EB25715E1500A9DD77 /* DownloadNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E0FD9EA25715E1500A9DD77 /* DownloadNotificationManager.swift */; };
4E1107AF256FE89900EB1711 /* DownloadStateNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1107AD256FCF2900EB1711 /* DownloadStateNotifier.swift */; };
4E1107B5256FFEC000EB1711 /* PEPNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1107B4256FFEC000EB1711 /* PEPNotification.swift */; };
/* End PBXBuildFile section */
@ -29,6 +30,7 @@
35943044248309BE00DCBD65 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = "<group>"; };
359430492483264F00DCBD65 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
3594304B2483266200DCBD65 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
4E0FD9EA25715E1500A9DD77 /* DownloadNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadNotificationManager.swift; sourceTree = "<group>"; };
4E1107AD256FCF2900EB1711 /* DownloadStateNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadStateNotifier.swift; sourceTree = "<group>"; };
4E1107B4256FFEC000EB1711 /* PEPNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PEPNotification.swift; sourceTree = "<group>"; };
4E4A391A2575452700BF0A15 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = "<group>"; };
@ -70,6 +72,7 @@
3527B2B124802F84007A6276 /* AppDelegate.swift */,
4E1107AD256FCF2900EB1711 /* DownloadStateNotifier.swift */,
4E1107B4256FFEC000EB1711 /* PEPNotification.swift */,
4E0FD9EA25715E1500A9DD77 /* DownloadNotificationManager.swift */,
3527B2B524802F87007A6276 /* Assets.xcassets */,
3527B2BD24802F87007A6276 /* Info.plist */,
3527B2BE24802F87007A6276 /* pEpNotifications.entitlements */,
@ -192,6 +195,7 @@
files = (
4E1107AF256FE89900EB1711 /* DownloadStateNotifier.swift in Sources */,
3527B2B224802F84007A6276 /* AppDelegate.swift in Sources */,
4E0FD9EB25715E1500A9DD77 /* DownloadNotificationManager.swift in Sources */,
4E1107B5256FFEC000EB1711 /* PEPNotification.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;


+ 50
- 17
Submodules/pEpNotifications/pEpNotifications/AppDelegate.swift View File

@ -9,6 +9,7 @@
import Cocoa
import SwiftUI
import UserNotifications
enum DNType : Int { case ready = 0, downloading, downloadArrived, noDownloadAvailable }
@ -40,6 +41,9 @@ class AppDelegate: NSObject {
private lazy var clientListener: NSXPCListener = NSXPCListener.anonymous()
private var receiver: PEPNotification?
private lazy var downloadStateNotifier = DownloadStateNotifier(at: statusText)
@available(OSX 10.14, *)
//private lazy var notificationCenter = UNUserNotificationCenter.current()
private lazy var downloadNotificationManager = DownloadNotificationManager()
// MARK: - Action methods
@ -124,8 +128,12 @@ extension AppDelegate {
}
private func initNotificationCenter() {
nc.removeAllDeliveredNotifications()
nc.delegate = self
if #available(OSX 10.14, *) {
downloadNotificationManager.delegate = self
} else {
nc.removeAllDeliveredNotifications()
nc.delegate = self
}
}
private func proxyErrorHandler(err: Error) -> Void {
@ -170,6 +178,11 @@ extension AppDelegate {
NSStatusBar.system.removeStatusItem(statusBarItem!)
statusBarItem = nil
}
}
// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
}
@ -191,21 +204,24 @@ extension AppDelegate: PEPNotificationProtocol {
}
case .downloadArrived:
removeDeliveredNotifications(with: withName)
let un = NSUserNotification()
un.title = NSLocalizedString("Update available", comment: "")
un.informativeText = String(format: NSLocalizedString("A new update for %@ is ready to be installed.", comment: ""), withName)
un.actionButtonTitle = NSLocalizedString("Install", comment: "")
un.hasActionButton = true
un.otherButtonTitle = NSLocalizedString("Not now", comment: "")
un.soundName = NSUserNotificationDefaultSoundName
let installTitle : String = NSLocalizedString("Install", comment: "")
un.additionalActions = [NSUserNotificationAction(identifier: "install", title: installTitle)]
un.setValue(true, forKey: "_showsButtons")
un.userInfo = ["name": withName, "filename": withFilename]
nc.deliver(un)
let product = ["name": withName, "filename": withFilename, "notification": un]
let product = ["name": withName, "filename": withFilename]
if #available(OSX 10.14, *) {
downloadNotificationManager.scheduleDownloadNotification(with: product)
} else {
removeDeliveredNotifications(with: withName)
let un = NSUserNotification()
un.title = NSLocalizedString("Update available", comment: "")
un.informativeText = String(format: NSLocalizedString("A new update for %@ is ready to be installed.", comment: ""), withName)
un.actionButtonTitle = NSLocalizedString("Install", comment: "")
un.hasActionButton = true
un.otherButtonTitle = NSLocalizedString("Not now", comment: "")
un.soundName = NSUserNotificationDefaultSoundName
un.setValue(true, forKey: "_showsButtons")
un.userInfo = ["name": withName, "filename": withFilename]
nc.deliver(un)
}
//let product = ["name": withName, "filename": withFilename, "notification": un]
downloadStateNotifier.notify(.NewVersionAvailable(String(withName)), with: product)
case .noDownloadAvailable:
@ -282,3 +298,20 @@ extension AppDelegate: NSXPCListenerDelegate {
return true
}
}
// MARK: - DownloadNotificationManagerDelegate
extension AppDelegate: DownloadNotificationManagerDelegate {
func installSelected(with product: Product) {
defer {
uninstallMenuExtra()
}
guard let filename = product["filename"] as? String else {
return
}
NSLog("pEpNotifications: actionButtonClicked for %@", filename)
NSWorkspace.shared.openFile(filename)
downloadStateNotifier.notify(.Connected)
}
}

+ 148
- 0
Submodules/pEpNotifications/pEpNotifications/DownloadNotificationManager.swift View File

@ -0,0 +1,148 @@
//
// 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
}
}
}

+ 1
- 1
Submodules/pEpNotifications/pEpNotifications/DownloadStateNotifier.swift View File

@ -8,7 +8,7 @@
import SwiftUI
typealias Product = Dictionary<String, Any>
public typealias Product = Dictionary<String, Any>
struct DownloadStateNotifier {
var menuItem: NSMenuItem


Loading…
Cancel
Save