// // AddWebFeedIntentHandler.swift // NetNewsWire // // Created by Maurice Parker on 10/18/19. // Copyright © 2019 Ranchero Software. All rights reserved. // import Intents public enum AddWebFeedIntentHandlerError: LocalizedError { case communicationFailure public var errorDescription: String? { switch self { case .communicationFailure: return NSLocalizedString("Unable to communicate with NetNewsWire.", comment: "Communication failure") } } } public class AddWebFeedIntentHandler: NSObject, AddWebFeedIntentHandling { override init() { super.init() } public func resolveUrl(for intent: AddWebFeedIntent, with completion: @escaping (AddWebFeedUrlResolutionResult) -> Void) { guard let url = intent.url else { completion(.unsupported(forReason: .required)) return } completion(.success(with: url)) } public func provideAccountNameOptions(for intent: AddWebFeedIntent, with completion: @escaping ([String]?, Error?) -> Void) { guard let extensionContainers = ExtensionContainersFile.read() else { completion(nil, AddWebFeedIntentHandlerError.communicationFailure) return } let accountNames = extensionContainers.accounts.map { $0.name } completion(accountNames, nil) } public func resolveAccountName(for intent: AddWebFeedIntent, with completion: @escaping (AddWebFeedAccountNameResolutionResult) -> Void) { guard let accountName = intent.accountName else { completion(AddWebFeedAccountNameResolutionResult.notRequired()) return } guard let extensionContainers = ExtensionContainersFile.read() else { completion(.unsupported(forReason: .communication)) return } if extensionContainers.findAccount(forName: accountName) == nil { completion(.unsupported(forReason: .invalid)) } else { completion(.success(with: accountName)) } } public func provideFolderNameOptions(for intent: AddWebFeedIntent, with completion: @escaping ([String]?, Error?) -> Void) { guard let extensionContainers = ExtensionContainersFile.read() else { completion(nil, AddWebFeedIntentHandlerError.communicationFailure) return } guard let accountName = intent.accountName, let account = extensionContainers.findAccount(forName: accountName) else { completion([String](), nil) return } let folderNames = account.folders.map { $0.name } completion(folderNames, nil) } public func resolveFolderName(for intent: AddWebFeedIntent, with completion: @escaping (AddWebFeedFolderNameResolutionResult) -> Void) { guard let accountName = intent.accountName, let folderName = intent.folderName else { completion(AddWebFeedFolderNameResolutionResult.notRequired()) return } guard let extensionContainers = ExtensionContainersFile.read() else { completion(.unsupported(forReason: .communication)) return } guard let account = extensionContainers.findAccount(forName: accountName) else { completion(.unsupported(forReason: .invalid)) return } if account.findFolder(forName: folderName) == nil { completion(.unsupported(forReason: .invalid)) } else { completion(.success(with: folderName)) } return } public func handle(intent: AddWebFeedIntent, completion: @escaping (AddWebFeedIntentResponse) -> Void) { guard let url = intent.url, let extensionContainers = ExtensionContainersFile.read() else { completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil)) return } let account: ExtensionAccount? = { if let accountName = intent.accountName { return extensionContainers.findAccount(forName: accountName) } else { return extensionContainers.accounts.first } }() guard let validAccount = account else { completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil)) return } let container: ExtensionContainer? = { if let folderName = intent.folderName { return validAccount.findFolder(forName: folderName) } else { return validAccount } }() guard let validContainer = container, let containerID = validContainer.containerID else { completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil)) return } let request = ExtensionFeedAddRequest(name: nil, feedURL: url, destinationContainerID: containerID) ExtensionFeedAddRequestFile.save(request) completion(AddWebFeedIntentResponse(code: .success, userActivity: nil)) } }