// // ExtensionPointManager.swift // NetNewsWire // // Created by Maurice Parker on 4/7/20. // Copyright © 2020 Ranchero Software. All rights reserved. // import Foundation import FeedProvider import RSCore public extension Notification.Name { static let ActiveExtensionPointsDidChange = Notification.Name(rawValue: "ActiveExtensionPointsDidChange") } final class ExtensionPointManager { static let shared = ExtensionPointManager() var activeExtensionPoints = [ExtensionPointIdentifer: ExtensionPoint]() let possibleExtensionPointTypes: [ExtensionPoint.Type] var availableExtensionPointTypes: [ExtensionPoint.Type] { let activeExtensionPointTypes = activeExtensionPoints.keys.compactMap({ ObjectIdentifier($0.type) }) var available = [ExtensionPoint.Type]() for possibleExtensionPointType in possibleExtensionPointTypes { if possibleExtensionPointType.isSinglton { if !activeExtensionPointTypes.contains(ObjectIdentifier(possibleExtensionPointType)) { available.append(possibleExtensionPointType) } } else { available.append(possibleExtensionPointType) } } return available } var activeSendToCommands: [SendToCommand] { return activeExtensionPoints.values.compactMap({ return $0 as? SendToCommand }) } var activeFeedProviders: [FeedProvider] { return activeExtensionPoints.values.compactMap({ return $0 as? FeedProvider }) } init() { #if os(macOS) #if DEBUG possibleExtensionPointTypes = [SendToMarsEditCommand.self, SendToMicroBlogCommand.self, TwitterFeedProvider.self] #else possibleExtensionPointTypes = [SendToMarsEditCommand.self, SendToMicroBlogCommand.self, TwitterFeedProvider.self] #endif #else #if DEBUG possibleExtensionPointTypes = [TwitterFeedProvider.self] #else possibleExtensionPointTypes = [TwitterFeedProvider.self] #endif #endif loadExtensionPoints() } func activateExtensionPoint(_ extensionPointType: ExtensionPoint.Type) { if let extensionPoint = self.extensionPoint(for: extensionPointType) { activeExtensionPoints[extensionPoint.extensionPointID] = extensionPoint saveExtensionPointIDs() } } func deactivateExtensionPoint(_ extensionPointID: ExtensionPointIdentifer) { activeExtensionPoints[extensionPointID] = nil saveExtensionPointIDs() } } private extension ExtensionPointManager { func loadExtensionPoints() { if let extensionPointUserInfos = AppDefaults.activeExtensionPointIDs { for extensionPointUserInfo in extensionPointUserInfos { if let extensionPointID = ExtensionPointIdentifer(userInfo: extensionPointUserInfo) { activeExtensionPoints[extensionPointID] = extensionPoint(for: extensionPointID) } } } } func saveExtensionPointIDs() { AppDefaults.activeExtensionPointIDs = activeExtensionPoints.keys.map({ $0.userInfo }) NotificationCenter.default.post(name: .ActiveExtensionPointsDidChange, object: nil, userInfo: nil) } func extensionPoint(for extensionPointType: ExtensionPoint.Type) -> ExtensionPoint? { switch extensionPointType { case is SendToMarsEditCommand.Type: return SendToMarsEditCommand() case is SendToMicroBlogCommand.Type: return SendToMicroBlogCommand() // case is TwitterFeedProvider.Type: // return TwitterFeedProvider(username: username) default: assertionFailure("Unrecognized Extension Point Type.") } return nil } func extensionPoint(for extensionPointID: ExtensionPointIdentifer) -> ExtensionPoint { switch extensionPointID { case .marsEdit: return SendToMarsEditCommand() case .microblog: return SendToMicroBlogCommand() case .twitter(let username): return TwitterFeedProvider(username: username) } } }