// // AddWebFeedIntentHandler.swift // NetNewsWire // // Created by Maurice Parker on 10/18/19. // Copyright © 2019 Ranchero Software. All rights reserved. // import Intents import Account public class AddWebFeedIntentHandler: NSObject, AddWebFeedIntentHandling { override init() { super.init() DispatchQueue.main.sync { AccountManager.shared = AccountManager() } } 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) { DispatchQueue.main.async { let accountNames = AccountManager.shared.activeAccounts.compactMap { $0.nameForDisplay } completion(accountNames, nil) } } public func resolveAccountName(for intent: AddWebFeedIntent, with completion: @escaping (AddWebFeedAccountNameResolutionResult) -> Void) { guard let accountName = intent.accountName else { completion(AddWebFeedAccountNameResolutionResult.notRequired()) return } DispatchQueue.main.async { if AccountManager.shared.findActiveAccount(forDisplayName: accountName) == nil { completion(.unsupported(forReason: .invalid)) } else { completion(.success(with: accountName)) } } } public func provideFolderNameOptions(for intent: AddWebFeedIntent, with completion: @escaping ([String]?, Error?) -> Void) { DispatchQueue.main.async { guard let accountName = intent.accountName, let account = AccountManager.shared.findActiveAccount(forDisplayName: accountName) else { completion([String](), nil) return } let folderNames = account.folders?.map { $0.nameForDisplay } 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 } DispatchQueue.main.async { guard let account = AccountManager.shared.findActiveAccount(forDisplayName: accountName) else { completion(.unsupported(forReason: .invalid)) return } if account.findFolder(withDisplayName: 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 else { completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil)) return } DispatchQueue.main.async { let account: Account? = { if let accountName = intent.accountName { return AccountManager.shared.findActiveAccount(forDisplayName: accountName) } else { return AccountManager.shared.sortedActiveAccounts.first } }() guard let validAccount = account else { completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil)) return } let container: Container? = { if let folderName = intent.folderName { return validAccount.findFolder(withDisplayName: folderName) } else { return validAccount } }() guard let validContainer = container else { completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil)) return } validAccount.createWebFeed(url: url.absoluteString, name: nil, container: validContainer) { result in switch result { case .success: completion(AddWebFeedIntentResponse(code: .success, userActivity: nil)) case .failure(let error): switch error { case AccountError.createErrorNotFound: completion(AddWebFeedIntentResponse(code: .feedNotFound, userActivity: nil)) case AccountError.createErrorAlreadySubscribed: completion(AddWebFeedIntentResponse(code: .alreadySubscribed, userActivity: nil)) default: completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil)) } } } } } }