Browse Source

MOS-8 Split to extensions. Create PEPNotification. Refactor.

MOS-8
David Alarcon 2 years ago
parent
commit
10bb50ead0
7 changed files with 179 additions and 126 deletions
  1. +4
    -0
      Submodules/pEpNotifications/pEpNotifications.xcodeproj/project.pbxproj
  2. +144
    -122
      Submodules/pEpNotifications/pEpNotifications/AppDelegate.swift
  3. +1
    -1
      Submodules/pEpNotifications/pEpNotifications/DownloadStateNotifier.swift
  4. +27
    -0
      Submodules/pEpNotifications/pEpNotifications/PEPNotification.swift
  5. +1
    -1
      pEpMacOSAdapter/PEPMacOSAdapterProtocol.h
  6. +1
    -1
      pEpMacOSAdapter/pEpMacOSAdapter.m
  7. +1
    -1
      pEpMacOSAdapter/pEpUpdater.h

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

@ -13,6 +13,7 @@
3594303F2483011000DCBD65 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3594303D2483011000DCBD65 /* Main.storyboard */; };
359430482483264F00DCBD65 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3594304A2483264F00DCBD65 /* Localizable.strings */; };
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 */
/* Begin PBXFileReference section */
@ -30,6 +31,7 @@
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>"; };
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>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -67,6 +69,7 @@
3594303D2483011000DCBD65 /* Main.storyboard */,
3527B2B124802F84007A6276 /* AppDelegate.swift */,
4E1107AD256FCF2900EB1711 /* DownloadStateNotifier.swift */,
4E1107B4256FFEC000EB1711 /* PEPNotification.swift */,
3527B2B524802F87007A6276 /* Assets.xcassets */,
3527B2BD24802F87007A6276 /* Info.plist */,
3527B2BE24802F87007A6276 /* pEpNotifications.entitlements */,
@ -189,6 +192,7 @@
files = (
4E1107AF256FE89900EB1711 /* DownloadStateNotifier.swift in Sources */,
3527B2B224802F84007A6276 /* AppDelegate.swift in Sources */,
4E1107B5256FFEC000EB1711 /* PEPNotification.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};


+ 144
- 122
Submodules/pEpNotifications/pEpNotifications/AppDelegate.swift View File

@ -12,10 +12,6 @@ import SwiftUI
enum DNType : Int { case ready = 0, downloading, downloadArrived, noDownloadAvailable }
@objc(PEPNotificationProtocol) protocol PEPNotificationProtocol {
func notifyDownload(_ type: Int, withName: NSString, withFilename: NSString)
}
@objc(PEPMacOSAdapterProtocol) protocol PEPMacOSAdapterProtocol {
func subscribeForUpdate(_ endpoint: NSXPCListenerEndpoint?)
func unsubscribeForUpdate()
@ -24,52 +20,28 @@ enum DNType : Int { case ready = 0, downloading, downloadArrived, noDownloadAvai
func stopUpdates()
}
@objc class pEpNotification : NSObject, PEPNotificationProtocol {
var delegate: PEPNotificationProtocol!
func notifyDownload(_ type: Int, withName: NSString, withFilename: NSString) {
NSLog("notifyDownload")
delegate?.notifyDownload(type, withName: withName, withFilename: withFilename)
}
}
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate, NSXPCListenerDelegate, PEPNotificationProtocol {
class AppDelegate: NSObject {
// MARK: - Outlets
@IBOutlet weak var pEpMenu: NSMenu!
@IBOutlet weak var statusText: NSMenuItem!
@IBOutlet weak var _updateNow: NSMenuItem!
@IBOutlet weak var _scheduleUpdates: NSMenuItem!
@IBOutlet weak var _alwaysShowThisMenu: NSMenuItem!
var statusBarItem: NSStatusItem? = nil
lazy var connection: NSXPCConnection = NSXPCConnection.init(machServiceName: "foundation.pEp.adapter.macOS")
var service: PEPMacOSAdapterProtocol?
var nc = NSUserNotificationCenter.default
lazy var clientListener: NSXPCListener = NSXPCListener.anonymous()
var receiver: pEpNotification!
lazy var downloadStateNotifier = DownloadStateNotifier(at: statusText)
// MARK: - Properties
@objc func installMenuExtra() {
guard statusBarItem == nil else {
return
}
statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
statusBarItem?.button?.title = "p≡p"
statusBarItem?.menu = NSApp.menu?.item(at: 0)?.submenu
_updateNow.action = #selector(updateNow)
}
private var statusBarItem: NSStatusItem? = nil
private lazy var connection: NSXPCConnection = NSXPCConnection.init(machServiceName: "foundation.pEp.adapter.macOS")
private var service: PEPMacOSAdapterProtocol?
private var nc = NSUserNotificationCenter.default
private lazy var clientListener: NSXPCListener = NSXPCListener.anonymous()
private var receiver: PEPNotification?
private lazy var downloadStateNotifier = DownloadStateNotifier(at: statusText)
func uninstallMenuExtra() {
guard
statusBarItem != nil && !UserDefaults.standard.bool(forKey: "AlwaysShowThisMenu")
else {
return
}
NSStatusBar.system.removeStatusItem(statusBarItem!)
statusBarItem = nil
}
// MARK: - Action methods
@IBAction func scheduleUpdates(_ sender: NSMenuItem) {
if sender.state == NSControl.StateValue.on {
@ -106,6 +78,104 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
sender.representedObject = nil
downloadStateNotifier.notify(.Connected)
}
}
// MARK: - Private
extension AppDelegate {
@objc
private func updateNow() {
nc.removeAllDeliveredNotifications()
service?.updateNow()
}
private func setupAppDefaults() {
let appDefaults = ["ScheduleUpdates": true, "AlwaysShowThisMenu": false]
UserDefaults.standard.register(defaults: appDefaults)
if UserDefaults.standard.bool(forKey: "AlwaysShowThisMenu") {
_alwaysShowThisMenu.state = NSControl.StateValue.on
installMenuExtra()
} else {
_alwaysShowThisMenu.state = NSControl.StateValue.off
}
}
private func initXPCConnection() {
connection.remoteObjectInterface = NSXPCInterface.init(with: PEPMacOSAdapterProtocol.self)
connection.resume()
service = connection.remoteObjectProxyWithErrorHandler(proxyErrorHandler) as? PEPMacOSAdapterProtocol
}
private func initClientService() {
clientListener.delegate = self
clientListener.resume()
}
private func setupServiceSubscription() {
service?.subscribeForUpdate(clientListener.endpoint)
if UserDefaults.standard.bool(forKey: "ScheduleUpdates") {
service?.scheduleUpdates()
_scheduleUpdates.state = NSControl.StateValue.on
}
else {
service?.stopUpdates()
_scheduleUpdates.state = NSControl.StateValue.off
}
}
private func initNotificationCenter() {
nc.removeAllDeliveredNotifications()
nc.delegate = self
}
private func proxyErrorHandler(err: Error) -> Void {
NSLog("%@", err.localizedDescription)
downloadStateNotifier.notify(.ConnectionFailed)
}
/// This removes _all_ previous notifications from a pEp product.
/// Currently there is only one pEp Product (pEp4Thunderbird) to take care of.
/// - Parameter productName: the pEp product name
private func removeDeliveredNotifications(with productName: NSString) {
nc.deliveredNotifications.forEach { notification in
guard
let userInfoName = notification.userInfo?["name"] as? NSString,
userInfoName == productName
else {
return
}
nc.removeDeliveredNotification(notification)
}
}
private func installMenuExtra() {
guard statusBarItem == nil else {
return
}
statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
statusBarItem?.button?.title = "p≡p"
statusBarItem?.menu = NSApp.menu?.item(at: 0)?.submenu
_updateNow.action = #selector(updateNow)
}
private func uninstallMenuExtra() {
guard
statusBarItem != nil && !UserDefaults.standard.bool(forKey: "AlwaysShowThisMenu")
else {
return
}
NSStatusBar.system.removeStatusItem(statusBarItem!)
statusBarItem = nil
}
}
// MARK: - PEPNotificationProtocol
extension AppDelegate: PEPNotificationProtocol {
func notifyDownload(_ type: Int, withName: NSString, withFilename: NSString) {
let _type = DNType.init(rawValue: type)
@ -113,7 +183,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
case .downloading:
NSLog("pEpNotifications: downloading")
downloadStateNotifier.notify(.Downloading(String(withName)))
self.performSelector(onMainThread: #selector(installMenuExtra), with:nil, waitUntilDone: false)
DispatchQueue.main.async { [weak self] in
guard let me = self else {
return
}
me.installMenuExtra()
}
case .downloadArrived:
removeDeliveredNotifications(with: withName)
@ -145,57 +220,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
break
}
}
/// This removes _all_ previous notifications from a pEp product.
/// Currently there is only one pEp Product (pEp4Thunderbird) to take care of.
/// - Parameter productName: the pEp product name
private func removeDeliveredNotifications(with productName: NSString) {
nc.deliveredNotifications.forEach { notification in
guard
let userInfoName = notification.userInfo?["name"] as? NSString,
userInfoName == productName
else {
return
}
nc.removeDeliveredNotification(notification)
}
}
@objc func updateNow() {
nc.removeAllDeliveredNotifications()
service?.updateNow()
}
@objc func userNotificationCenter(_ : NSUserNotificationCenter, didActivate: NSUserNotification) {
guard
didActivate.activationType == NSUserNotification.ActivationType.actionButtonClicked
else {
return
}
uninstallMenuExtra()
let filename : String = didActivate.userInfo?["filename"] as! String
NSLog("pEpNotifications: actionButtonClicked for %@", filename)
NSWorkspace.shared.openFile(filename)
downloadStateNotifier.notify(.Connected)
}
func proxyErrorHandler(err: Error) -> Void {
NSLog("%@", err.localizedDescription)
downloadStateNotifier.notify(.ConnectionFailed)
}
}
@objc func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
newConnection.exportedInterface = NSXPCInterface.init(with: PEPNotificationProtocol.self)
let obj = pEpNotification()
obj.delegate = self
newConnection.exportedObject = obj
newConnection.resume()
// MARK: - NSApplicationDelegate
return true
}
extension AppDelegate: NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// preference defaults
setupAppDefaults()
@ -220,43 +249,36 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
service?.unsubscribeForUpdate()
connection.invalidate()
}
}
private func setupAppDefaults() {
let appDefaults = ["ScheduleUpdates": true, "AlwaysShowThisMenu": false]
UserDefaults.standard.register(defaults: appDefaults)
if UserDefaults.standard.bool(forKey: "AlwaysShowThisMenu") {
_alwaysShowThisMenu.state = NSControl.StateValue.on
installMenuExtra()
} else {
_alwaysShowThisMenu.state = NSControl.StateValue.off
// MARK: - NSUserNotificationCenterDelegate
extension AppDelegate: NSUserNotificationCenterDelegate {
@objc func userNotificationCenter(_ : NSUserNotificationCenter, didActivate: NSUserNotification) {
guard
didActivate.activationType == NSUserNotification.ActivationType.actionButtonClicked
else {
return
}
}
private func initXPCConnection() {
connection.remoteObjectInterface = NSXPCInterface.init(with: PEPMacOSAdapterProtocol.self)
connection.resume()
service = connection.remoteObjectProxyWithErrorHandler(proxyErrorHandler) as? PEPMacOSAdapterProtocol
uninstallMenuExtra()
let filename : String = didActivate.userInfo?["filename"] as! String
NSLog("pEpNotifications: actionButtonClicked for %@", filename)
NSWorkspace.shared.openFile(filename)
downloadStateNotifier.notify(.Connected)
}
}
private func initClientService() {
clientListener.delegate = self
clientListener.resume()
}
// MARK: - NSXPCListenerDelegate
private func setupServiceSubscription() {
service?.subscribeForUpdate(clientListener.endpoint)
if UserDefaults.standard.bool(forKey: "ScheduleUpdates") {
service?.scheduleUpdates()
_scheduleUpdates.state = NSControl.StateValue.on
}
else {
service?.stopUpdates()
_scheduleUpdates.state = NSControl.StateValue.off
}
}
extension AppDelegate: NSXPCListenerDelegate {
@objc func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
newConnection.exportedInterface = NSXPCInterface.init(with: PEPNotificationProtocol.self)
let obj = PEPNotification()
obj.delegate = self
newConnection.exportedObject = obj
newConnection.resume()
private func initNotificationCenter() {
nc.removeAllDeliveredNotifications()
nc.delegate = self
return true
}
}

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

@ -24,7 +24,7 @@ struct DownloadStateNotifier {
}
}
enum DownloadState {
public enum DownloadState {
case Connecting
case Connected


+ 27
- 0
Submodules/pEpNotifications/pEpNotifications/PEPNotification.swift View File

@ -0,0 +1,27 @@
//
// PEPNotification.swift
// pp updates
//
// Created by David Alarcon on 26/11/2020.
// Copyright © 2020 pp foundation. All rights reserved.
//
import Foundation
@objc(PEPNotificationProtocol) protocol PEPNotificationProtocol {
func notifyDownload(_ type: Int, withName: NSString, withFilename: NSString)
}
@objc class PEPNotification : NSObject {
// Intentionally not weak, No one else holds strong pointer to it.
var delegate: PEPNotificationProtocol?
}
// MARK: - PEPNotificationProtocol
extension PEPNotification: PEPNotificationProtocol {
func notifyDownload(_ type: Int, withName: NSString, withFilename: NSString) {
NSLog("notifyDownload")
delegate?.notifyDownload(type, withName: withName, withFilename: withFilename)
}
}

+ 1
- 1
pEpMacOSAdapter/PEPMacOSAdapterProtocol.h View File

@ -21,7 +21,7 @@ typedef enum { ready = 0, downloading, downloadArrived, noDownloadAvailable } DN
@end
/// This is the object from the client where we deliver notifications to
@interface pEpNotification : NSObject <PEPNotificationProtocol>
@interface PEPNotification : NSObject <PEPNotificationProtocol>
@end
/// This protocol is providing the XPC interface to the User Interface program pEpNotifications


+ 1
- 1
pEpMacOSAdapter/pEpMacOSAdapter.m View File

@ -33,7 +33,7 @@ extern pEpUpdater* updater;
[_clientConnection resume];
pEpNotification* downloadNotification = [_clientConnection remoteObjectProxyWithErrorHandler:^(NSError*err) {
PEPNotification* downloadNotification = [_clientConnection remoteObjectProxyWithErrorHandler:^(NSError*err) {
NSLog(@"%@", err);
}];


+ 1
- 1
pEpMacOSAdapter/pEpUpdater.h View File

@ -20,7 +20,7 @@
@property (retain) NSString* configPath;
/// subscriber for notifications
@property (retain) pEpNotification* subscriber;
@property (retain) PEPNotification* subscriber;
/// initializes the pEpUpdater
- (id)init;


Loading…
Cancel
Save