import Foundation class RemoteNotificationsRefreshCrossWikiGroupOperation: RemoteNotificationsOperation { enum CrossWikiGroupError: LocalizedError { case individualErrors([Error]) var errorDescription: String? { switch self { case .individualErrors(let errors): if let firstError = errors.first { return (firstError as NSError).alertMessage() } } return CommonStrings.genericErrorDescription } } var crossWikiSummaryNotification: RemoteNotificationsAPIController.NotificationsResult.Notification? private let internalQueue = OperationQueue() private let finishingOperation = BlockOperation(block: {}) private let appLanguageProject: WikimediaProject private let secondaryProjects: [WikimediaProject] private let languageLinkController: MWKLanguageLinkController init(appLanguageProject: WikimediaProject, secondaryProjects: [WikimediaProject], languageLinkController: MWKLanguageLinkController, apiController: RemoteNotificationsAPIController, modelController: RemoteNotificationsModelController) { self.appLanguageProject = appLanguageProject self.secondaryProjects = secondaryProjects self.languageLinkController = languageLinkController super.init(apiController: apiController, modelController: modelController) } required init(apiController: RemoteNotificationsAPIController, modelController: RemoteNotificationsModelController) { fatalError("init(apiController:modelController:) has not been implemented") } override func execute() { let crossWikiOperations = crossWikiOperations() for crossWikiOperation in crossWikiOperations { finishingOperation.addDependency(crossWikiOperation) } finishingOperation.completionBlock = { let errors = crossWikiOperations.compactMap { $0.error } if errors.count > 0 { self.finish(with: CrossWikiGroupError.individualErrors(errors)) } else { self.finish() } } internalQueue.addOperations(crossWikiOperations + [finishingOperation], waitUntilFinished: false) } override func cancel() { internalQueue.cancelAllOperations() super.cancel() } private func crossWikiOperations() -> [RemoteNotificationsRefreshCrossWikiOperation] { guard let crossWikiSummary = crossWikiSummaryNotification, let crossWikiSources = crossWikiSummary.sources else { return [] } let crossWikiProjects = crossWikiSources.keys.compactMap { WikimediaProject(notificationsApiIdentifier: $0, languageLinkController: languageLinkController) } // extract new projects from summary object that aren't already queued up to be fetched as an app language or secondary operation let filteredCrossWikiProjects = crossWikiProjects.filter { !([appLanguageProject] + secondaryProjects).contains($0) } return filteredCrossWikiProjects.map { RemoteNotificationsRefreshCrossWikiOperation(project: $0, apiController: self.apiController, modelController: self.modelController, needsCrossWikiSummary: false)} } } class RemoteNotificationsRefreshCrossWikiOperation: RemoteNotificationsPagingOperation { override var filter: RemoteNotificationsAPIController.Query.Filter { return .unread } }