diff --git a/Account/Sources/Account/Account.swift b/Account/Sources/Account/Account.swift index 8b8c01581..7a8c01698 100644 --- a/Account/Sources/Account/Account.swift +++ b/Account/Sources/Account/Account.swift @@ -497,9 +497,11 @@ public enum FetchType { } else { if let title = item.titleFromAttributes, let folder = ensureFolder(with: title) { folder.externalID = item.attributes?["nnw_externalID"] as? String - item.children?.forEach { itemChild in - if let feedSpecifier = itemChild.feedSpecifier { - folder.addFeed(newFeed(with: feedSpecifier)) + if let children = item.children { + for itemChild in children { + if let feedSpecifier = itemChild.feedSpecifier { + folder.addFeed(newFeed(with: feedSpecifier)) + } } } } @@ -535,9 +537,12 @@ public enum FetchType { if topLevelFeeds.contains(feed) { containers.append(self) } - folders?.forEach { folder in - if folder.topLevelFeeds.contains(feed) { - containers.append(folder) + + if let folders { + for folder in folders { + if folder.topLevelFeeds.contains(feed) { + containers.append(folder) + } } } return containers @@ -952,7 +957,9 @@ public enum FetchType { public func debugDropConditionalGetInfo() { #if DEBUG - flattenedFeeds().forEach{ $0.dropConditionalGetInfo() } + for feed in flattenedFeeds() { + feed.dropConditionalGetInfo() + } #endif } @@ -1176,7 +1183,7 @@ private extension Account { var idDictionary = [String: Feed]() var externalIDDictionary = [String: Feed]() - flattenedFeeds().forEach { (feed) in + for feed in flattenedFeeds() { idDictionary[feed.feedID] = feed if let externalID = feed.externalID { externalIDDictionary[externalID] = feed diff --git a/Account/Sources/Account/AccountDelegates/FeedbinAccountDelegate.swift b/Account/Sources/Account/AccountDelegates/FeedbinAccountDelegate.swift index 84ee8c39c..c7eb635bf 100644 --- a/Account/Sources/Account/AccountDelegates/FeedbinAccountDelegate.swift +++ b/Account/Sources/Account/AccountDelegates/FeedbinAccountDelegate.swift @@ -985,12 +985,11 @@ private extension FeedbinAccountDelegate { // Feedbin has a tag that we don't have a folder for. We might not get a new // taggings response for it if it is a folder rename. Force expire the tagging // so that we will for sure get the new tagging information. - tags.forEach { tag in + for tag in tags { if !folderNames.contains(tag.name) { accountMetadata?.conditionalGetInfo[FeedbinAPICaller.ConditionalGetKeys.taggings] = nil } } - } func syncFolders(_ account: Account, _ tags: [FeedbinTag]?) { @@ -1003,7 +1002,7 @@ private extension FeedbinAccountDelegate { // Delete any folders not at Feedbin if let folders = account.folders { - folders.forEach { folder in + for folder in folders { if !tagNames.contains(folder.name ?? "") { for feed in folder.topLevelFeeds { account.addFeed(feed) @@ -1023,12 +1022,11 @@ private extension FeedbinAccountDelegate { }() // Make any folders Feedbin has, but we don't - tagNames.forEach { tagName in + for tagName in tagNames { if !folderNames.contains(tagName) { _ = account.ensureFolder(with: tagName) } } - } func syncFeeds(_ account: Account, _ subscriptions: [FeedbinSubscription]?) { @@ -1059,7 +1057,7 @@ private extension FeedbinAccountDelegate { // Add any feeds we don't have and update any we do var subscriptionsToAdd = Set() - subscriptions.forEach { subscription in + for subscription in subscriptions { let subFeedID = String(subscription.feedID) @@ -1078,7 +1076,7 @@ private extension FeedbinAccountDelegate { } // Actually add subscriptions all in one go, so we don’t trigger various rebuilding things that Account does. - subscriptionsToAdd.forEach { subscription in + for subscription in subscriptionsToAdd { let feed = account.createFeed(with: subscription.name, url: subscription.url, feedID: String(subscription.feedID), homePageURL: subscription.homePageURL) feed.externalID = String(subscription.subscriptionID) account.addFeed(feed) diff --git a/Account/Sources/Account/AccountDelegates/NewsBlurAccountDelegate+Internal.swift b/Account/Sources/Account/AccountDelegates/NewsBlurAccountDelegate+Internal.swift index d079a2970..4efbe0ed5 100644 --- a/Account/Sources/Account/AccountDelegates/NewsBlurAccountDelegate+Internal.swift +++ b/Account/Sources/Account/AccountDelegates/NewsBlurAccountDelegate+Internal.swift @@ -50,7 +50,7 @@ extension NewsBlurAccountDelegate { // Delete any folders not at NewsBlur if let folders = account.folders { - folders.forEach { folder in + for folder in folders { if !folderNames.contains(folder.name ?? "") { for feed in folder.topLevelFeeds { account.addFeed(feed) @@ -71,7 +71,7 @@ extension NewsBlurAccountDelegate { // Make any folders NewsBlur has, but we don't // Ignore account-level folder - folderNames.forEach { folderName in + for folderName in folderNames { if !accountFolderNames.contains(folderName) && folderName != " " { _ = account.ensureFolder(with: folderName) } @@ -122,7 +122,7 @@ extension NewsBlurAccountDelegate { } // Actually add feeds all in one go, so we don’t trigger various rebuilding things that Account does. - feedsToAdd.forEach { feed in + for feed in feedsToAdd { let feed = account.createFeed(with: feed.name, url: feed.feedURL, feedID: String(feed.feedID), homePageURL: feed.homePageURL) feed.externalID = String(feed.feedID) account.addFeed(feed) diff --git a/Account/Sources/Account/AccountDelegates/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/AccountDelegates/ReaderAPIAccountDelegate.swift index 9d1b00662..c00035444 100644 --- a/Account/Sources/Account/AccountDelegates/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/AccountDelegates/ReaderAPIAccountDelegate.swift @@ -534,7 +534,7 @@ private extension ReaderAPIAccountDelegate { // Delete any folders not at Reader if let folders = account.folders { - folders.forEach { folder in + for folder in folders { if !readerFolderExternalIDs.contains(folder.externalID ?? "") { for feed in folder.topLevelFeeds { account.addFeed(feed) @@ -554,13 +554,12 @@ private extension ReaderAPIAccountDelegate { }() // Make any folders Reader has, but we don't - folderTags.forEach { tag in + for tag in folderTags { if !folderExternalIDs.contains(tag.tagID) { let folder = account.ensureFolder(with: tag.folderName ?? "None") folder?.externalID = tag.tagID } } - } func syncFeeds(_ account: Account, _ subscriptions: [ReaderAPISubscription]?) { @@ -591,8 +590,8 @@ private extension ReaderAPIAccountDelegate { } // Add any feeds we don't have and update any we do - subscriptions.forEach { subscription in - + for subscription in subscriptions { + if let feed = account.existingFeed(withFeedID: subscription.feedID) { feed.name = subscription.name feed.editedName = nil @@ -617,14 +616,14 @@ private extension ReaderAPIAccountDelegate { let taggingsDict = subscriptions.reduce([String: [ReaderAPISubscription]]()) { (dict, subscription) in var taggedFeeds = dict - subscription.categories.forEach({ (category) in + for category in subscription.categories { if var taggedFeed = taggedFeeds[category.categoryID] { taggedFeed.append(subscription) taggedFeeds[category.categoryID] = taggedFeed } else { taggedFeeds[category.categoryID] = [subscription] } - }) + } return taggedFeeds } diff --git a/Account/Sources/Account/AccountManager.swift b/Account/Sources/Account/AccountManager.swift index 21b19b5de..ad6a2568b 100644 --- a/Account/Sources/Account/AccountManager.swift +++ b/Account/Sources/Account/AccountManager.swift @@ -201,17 +201,25 @@ import Secrets public func suspendNetworkAll() { isSuspended = true - accounts.forEach { $0.suspendNetwork() } + for account in accounts { + account.suspendNetwork() + } } public func suspendDatabaseAll() { - accounts.forEach { $0.suspendDatabase() } + for account in accounts { + account.suspendDatabase() + } } public func resumeAll() { isSuspended = false - accounts.forEach { $0.resumeDatabaseAndDelegate() } - accounts.forEach { $0.resume() } + for account in accounts { + account.resumeDatabaseAndDelegate() + } + for account in accounts { + account.resume() + } } public func receiveRemoteNotification(userInfo: [AnyHashable : Any]) async { @@ -279,7 +287,9 @@ import Secrets } public func saveAll() { - accounts.forEach { $0.save() } + for account in accounts { + account.save() + } } public func anyAccountHasAtLeastOneFeed() -> Bool { @@ -389,13 +399,15 @@ private extension AccountManager { filenames = filenames?.sorted() - filenames?.forEach { (oneFilename) in - guard oneFilename != defaultAccountFolderName else { - return - } - if let oneAccount = loadAccount(oneFilename) { - if !duplicateServiceAccount(oneAccount) { - accountsDictionary[oneAccount.accountID] = oneAccount + if let filenames { + for oneFilename in filenames { + guard oneFilename != defaultAccountFolderName else { + continue + } + if let oneAccount = loadAccount(oneFilename) { + if !duplicateServiceAccount(oneAccount) { + accountsDictionary[oneAccount.accountID] = oneAccount + } } } } diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift index ed0bd49f6..7da6a9a6e 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift @@ -84,9 +84,9 @@ import CloudKitExtras func removeFeed(_ externalID: String) { if let feed = account?.existingFeed(withExternalID: externalID), let containers = account?.existingContainers(withFeed: feed) { - containers.forEach { + for container in containers { feed.dropConditionalGetInfo() - $0.removeFeed(feed) + container.removeFeed(feed) } } } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift index a4ce57405..08b74c91a 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift @@ -96,7 +96,7 @@ final class FeedlyCreateFeedsForCollectionFoldersOperation: FeedlyOperation { } os_log(.debug, log: log, "Processing %i feeds.", feedsAndFolders.count) - feedsAndFolders.forEach { (feed, folder) in + for (feed, folder) in feedsAndFolders { if !folder.has(feed) { folder.addFeed(feed) } diff --git a/Account/Sources/Account/OPMLNormalizer.swift b/Account/Sources/Account/OPMLNormalizer.swift index 55c0a1cd6..ab6111f89 100644 --- a/Account/Sources/Account/OPMLNormalizer.swift +++ b/Account/Sources/Account/OPMLNormalizer.swift @@ -22,13 +22,13 @@ final class OPMLNormalizer { private func normalize(_ items: [RSOPMLItem], parentFolder: RSOPMLItem? = nil) { var feedsToAdd = [RSOPMLItem]() - items.forEach { (item) in + for item in items { if let _ = item.feedSpecifier { if !feedsToAdd.contains(where: { $0.feedSpecifier?.feedURL == item.feedSpecifier?.feedURL }) { feedsToAdd.append(item) } - return + continue } guard let _ = item.titleFromAttributes else { @@ -36,7 +36,7 @@ final class OPMLNormalizer { if let itemChildren = item.children { normalize(itemChildren, parentFolder: parentFolder) } - return + continue } feedsToAdd.append(item) diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift index 6277431d3..fa78de31c 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift @@ -163,7 +163,7 @@ private extension SearchTable { let groupedSearchInfos = Dictionary(grouping: searchInfos, by: { $0.rowID }) let searchInfosDictionary = groupedSearchInfos.mapValues { $0.first! } - articles.forEach { (article) in + for article in articles { updateIndexForArticle(article, searchInfosDictionary, database) } } diff --git a/Core/Sources/Core/CoalescingQueue.swift b/Core/Sources/Core/CoalescingQueue.swift index 94c7f5de0..cdcf01924 100644 --- a/Core/Sources/Core/CoalescingQueue.swift +++ b/Core/Sources/Core/CoalescingQueue.swift @@ -59,7 +59,9 @@ struct QueueCall: Equatable { guard !isPaused else { return } let callsToMake = calls // Make a copy in case calls are added to the queue while performing calls. resetCalls() - callsToMake.forEach { $0.perform() } + for call in callsToMake { + call.perform() + } } @objc func timerDidFire(_ sender: Any?) { diff --git a/Core/Sources/Core/MainThreadOperationQueue.swift b/Core/Sources/Core/MainThreadOperationQueue.swift index dba872bd5..e9ec54fc3 100644 --- a/Core/Sources/Core/MainThreadOperationQueue.swift +++ b/Core/Sources/Core/MainThreadOperationQueue.swift @@ -65,7 +65,9 @@ public protocol MainThreadOperationDelegate: AnyObject { /// Add multiple operations to the queue. /// This has the same effect as calling addOperation one-by-one. @MainActor public func addOperations(_ operations: [MainThreadOperation]) { - operations.forEach{ add($0) } + for operation in operations { + add(operation) + } } /// Add a dependency. Do this *before* calling addOperation, since addOperation might run the operation right away. @@ -450,16 +452,22 @@ private extension MainThreadOperationDependencies { } func removeDependencies(_ parentOperationIDs: [Int]) { - parentOperationIDs.forEach { dependencies[$0] = nil } + for parentOperationID in parentOperationIDs { + dependencies[parentOperationID] = nil + } } func removeChildOperationIDs(_ operationIDs: [Int]) { - operationIDs.forEach{ removeChildOperationID($0) } + for operationID in operationIDs { + removeChildOperationID(operationID) + } removeEmptyDependencies() } func removeChildOperationID(_ operationID: Int) { - dependencies.values.forEach{ $0.remove(operationID) } + for dependency in dependencies.values { + dependency.remove(operationID) + } } func removeEmptyDependencies() { diff --git a/Core/Sources/Core/UndoableCommand.swift b/Core/Sources/Core/UndoableCommand.swift index 69251d645..f53fda9f0 100644 --- a/Core/Sources/Core/UndoableCommand.swift +++ b/Core/Sources/Core/UndoableCommand.swift @@ -70,7 +70,10 @@ public extension UndoableCommandRunner { guard let undoManager = undoManager else { return } - undoableCommands.forEach { undoManager.removeAllActions(withTarget: $0) } + + for command in undoableCommands { + undoManager.removeAllActions(withTarget: command) + } undoableCommands = [UndoableCommand]() } } diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index e9829aa40..7c6df05d9 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -722,7 +722,9 @@ extension AppDelegate { @IBAction func debugDropConditionalGetInfo(_ sender: Any?) { #if DEBUG - accountManager.activeAccounts.forEach{ $0.debugDropConditionalGetInfo() } + for account in accountManager.activeAccounts { + account.debugDropConditionalGetInfo() + } #endif } diff --git a/Mac/MainWindow/AddFeed/FolderTreeMenu.swift b/Mac/MainWindow/AddFeed/FolderTreeMenu.swift index 6130ad352..d927fe7b8 100644 --- a/Mac/MainWindow/AddFeed/FolderTreeMenu.swift +++ b/Mac/MainWindow/AddFeed/FolderTreeMenu.swift @@ -62,7 +62,7 @@ import Core private static func addFolderItemsToMenuWithNodes(menu: NSMenu, nodes: [Node], indentationLevel: Int) { - nodes.forEach { (oneNode) in + for oneNode in nodes { if let nameProvider = oneNode.representedObject as? DisplayNameProvider { diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift index 7f9c9ae48..d4ed1155d 100644 --- a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift +++ b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift @@ -376,7 +376,7 @@ private extension SidebarOutlineDataSource { return false } - draggedNodes.forEach { node in + for node in draggedNodes { if sameAccount(node, parentNode) { if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { copyFeedInAccount(node: node, to: parentNode) @@ -453,7 +453,7 @@ private extension SidebarOutlineDataSource { return false } - draggedNodes.forEach { node in + for node in draggedNodes { if !sameAccount(node, parentNode) { copyFolderBetweenAccounts(node: node, to: parentNode) } diff --git a/Mac/MainWindow/Sidebar/SidebarViewController.swift b/Mac/MainWindow/Sidebar/SidebarViewController.swift index 79774bdc9..82207815f 100644 --- a/Mac/MainWindow/Sidebar/SidebarViewController.swift +++ b/Mac/MainWindow/Sidebar/SidebarViewController.swift @@ -114,8 +114,10 @@ protocol SidebarDelegate: AnyObject { } let selectedFeedIdentifers = Set(selectedFeedsState.compactMap( { SidebarItemIdentifier(userInfo: $0) })) - selectedFeedIdentifers.forEach { treeControllerDelegate.addFilterException($0) } - + for feedIdentifier in selectedFeedIdentifers { + treeControllerDelegate.addFilterException(feedIdentifier) + } + rebuildTreeAndReloadDataIfNeeded() var selectIndexes = IndexSet() @@ -550,7 +552,9 @@ private extension SidebarViewController { } func addAllSelectedToFilterExceptions() { - selectedFeeds.forEach { addToFilterExeptionsIfNecessary($0) } + for feed in selectedFeeds { + addToFilterExeptionsIfNecessary(feed) + } } func addToFilterExeptionsIfNecessary(_ feed: SidebarItem?) { @@ -593,13 +597,12 @@ private extension SidebarViewController { restoreSelection(to: savedSelection, sendNotificationIfChanged: true) // Automatically expand any new or newly active accounts - AccountManager.shared.activeAccounts.forEach { account in + for account in AccountManager.shared.activeAccounts { if !savedAccounts.contains(account) { let accountNode = treeController.nodeInTreeRepresentingObject(account) outlineView.expandItem(accountNode) } } - } func rebuildTreeAndReloadDataIfNeeded() { diff --git a/Mac/MainWindow/Timeline/Cell/TimelineCellLayout.swift b/Mac/MainWindow/Timeline/Cell/TimelineCellLayout.swift index 08fb41441..c3448b0ea 100644 --- a/Mac/MainWindow/Timeline/Cell/TimelineCellLayout.swift +++ b/Mac/MainWindow/Timeline/Cell/TimelineCellLayout.swift @@ -230,7 +230,9 @@ private extension Array where Element == NSRect { func maxY() -> CGFloat { var y: CGFloat = 0.0 - self.forEach { y = Swift.max(y, $0.maxY) } + for r in self { + y = Swift.max(y, r.maxY) + } return y } } diff --git a/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift b/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift index 26ce001d5..a9e6abe4a 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift @@ -212,7 +212,7 @@ private extension TimelineViewController { } let menu = NSMenu(title: NSLocalizedString("Share", comment: "Share menu name")) - services.forEach { (service) in + for service in services { service.delegate = sharingServiceDelegate let menuItem = NSMenuItem(title: service.menuItemTitle, action: #selector(performShareServiceFromContextualMenu(_:)), keyEquivalent: "") menuItem.image = service.image diff --git a/Mac/MainWindow/Timeline/TimelineViewController.swift b/Mac/MainWindow/Timeline/TimelineViewController.swift index f2ec43eaf..254d2f4e8 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController.swift @@ -1069,7 +1069,7 @@ private extension TimelineViewController { func updateArticleRowMap() { var rowMap = [String: [Int]]() var index = 0 - articles.forEach { (article) in + for article in articles { if var indexes = rowMap[article.articleID] { indexes.append(index) rowMap[article.articleID] = indexes @@ -1090,9 +1090,9 @@ private extension TimelineViewController { func indexesForArticleIDs(_ articleIDs: Set) -> IndexSet { var indexes = IndexSet() - articleIDs.forEach { (articleID) in + for articleID in articleIDs { guard let rowsIndex = rows(for: articleID) else { - return + continue } for rowIndex in rowsIndex { indexes.insert(rowIndex) diff --git a/NewsBlur/Sources/NewsBlur/Models/NewsBlurFeed.swift b/NewsBlur/Sources/NewsBlur/Models/NewsBlurFeed.swift index 645ceada0..c210d7a8d 100644 --- a/NewsBlur/Sources/NewsBlur/Models/NewsBlurFeed.swift +++ b/NewsBlur/Sources/NewsBlur/Models/NewsBlurFeed.swift @@ -84,7 +84,7 @@ extension NewsBlurFeedsResponse { // Parse feeds var feeds: [NewsBlurFeed] = [] let feedContainer = try container.nestedContainer(keyedBy: NewsBlurGenericCodingKeys.self, forKey: .feeds) - try feedContainer.allKeys.forEach { key in + for key in feedContainer.allKeys { let feed = try feedContainer.decode(NewsBlurFeed.self, forKey: key) feeds.append(feed) } diff --git a/ReaderAPI/Sources/ReaderAPI/ReaderAPICaller.swift b/ReaderAPI/Sources/ReaderAPI/ReaderAPICaller.swift index d7b176b84..e82f51288 100644 --- a/ReaderAPI/Sources/ReaderAPI/ReaderAPICaller.swift +++ b/ReaderAPI/Sources/ReaderAPI/ReaderAPICaller.swift @@ -123,12 +123,12 @@ public enum CreateReaderAPISubscriptionResult: Sendable { } var authData: [String: String] = [:] - rawData.split(separator: "\n").forEach({ (line: Substring) in - let items = line.split(separator: "=").map{String($0)} + for line in rawData.split(separator: "\n") { + let items = line.split(separator: "=").map { String($0) } if items.count == 2 { authData[items[0]] = items[1] } - }) + } guard let authString = authData["Auth"] else { throw CredentialsError.incompleteCredentials diff --git a/Shared/Commands/DeleteCommand.swift b/Shared/Commands/DeleteCommand.swift index 09de26a71..a4c8324e7 100644 --- a/Shared/Commands/DeleteCommand.swift +++ b/Shared/Commands/DeleteCommand.swift @@ -48,9 +48,9 @@ import Core func perform() { let group = DispatchGroup() - itemSpecifiers.forEach { + for itemSpecifier in itemSpecifiers { group.enter() - $0.delete() { + itemSpecifier.delete() { group.leave() } } @@ -59,11 +59,12 @@ import Core self.treeController?.rebuild() self.registerUndo() } - } func undo() { - itemSpecifiers.forEach { $0.restore() } + for itemSpecifier in itemSpecifiers { + itemSpecifier.restore() + } registerRedo() } diff --git a/Shared/ExtensionPoints/SendToMarsEditCommand.swift b/Shared/ExtensionPoints/SendToMarsEditCommand.swift index 560d32959..fb2533f80 100644 --- a/Shared/ExtensionPoints/SendToMarsEditCommand.swift +++ b/Shared/ExtensionPoints/SendToMarsEditCommand.swift @@ -57,7 +57,9 @@ private extension SendToMarsEditCommand { func appToUse() -> UserApp? { - marsEditApps.forEach{ $0.updateStatus() } + for app in marsEditApps { + app.updateStatus() + } for app in marsEditApps { if app.isRunning { diff --git a/Shared/ShareExtension/ExtensionFeedAddRequestFile.swift b/Shared/ShareExtension/ExtensionFeedAddRequestFile.swift index 9e4a29a37..d9bf00f4f 100644 --- a/Shared/ShareExtension/ExtensionFeedAddRequestFile.swift +++ b/Shared/ShareExtension/ExtensionFeedAddRequestFile.swift @@ -111,25 +111,29 @@ private extension ExtensionFeedAddRequestFile { fileCoordinator.coordinate(writingItemAt: fileURL, options: [.forMerging], error: errorPointer, byAccessor: { url in do { - + if let fileData = try? Data(contentsOf: url), - let decodedRequests = try? decoder.decode([ExtensionFeedAddRequest].self, from: fileData) { + let decodedRequests = try? decoder.decode([ExtensionFeedAddRequest].self, from: fileData) { requests = decodedRequests } - + let data = try encoder.encode([ExtensionFeedAddRequest]()) try data.write(to: url) - + } catch let error as NSError { os_log(.error, log: Self.log, "Save to disk failed: %@.", error.localizedDescription) } }) - + if let error = errorPointer?.pointee { os_log(.error, log: Self.log, "Save to disk coordination failed: %@.", error.localizedDescription) } - requests?.forEach { processRequest($0) } + if let requests { + for request in requests { + processRequest(request) + } + } } @MainActor func processRequest(_ request: ExtensionFeedAddRequest) { diff --git a/Shared/SmartFeeds/SmartFeed.swift b/Shared/SmartFeeds/SmartFeed.swift index 78c5f282e..472a0a089 100644 --- a/Shared/SmartFeeds/SmartFeed.swift +++ b/Shared/SmartFeeds/SmartFeed.swift @@ -68,7 +68,7 @@ final class SmartFeed: PseudoFeed { // Remove any accounts that are no longer active or have been deleted let activeAccountIDs = activeAccounts.map { $0.accountID } - unreadCounts.keys.forEach { accountID in + for accountID in unreadCounts.keys { if !activeAccountIDs.contains(accountID) { unreadCounts.removeValue(forKey: accountID) } diff --git a/Shared/Timeline/FetchRequestQueue.swift b/Shared/Timeline/FetchRequestQueue.swift index a35c39e05..c61c1addc 100644 --- a/Shared/Timeline/FetchRequestQueue.swift +++ b/Shared/Timeline/FetchRequestQueue.swift @@ -22,7 +22,9 @@ import Foundation func cancelAllRequests() { precondition(Thread.isMainThread) - pendingRequests.forEach { $0.isCanceled = true } + for request in pendingRequests { + request.isCanceled = true + } currentRequest?.isCanceled = true pendingRequests = [FetchRequestOperation]() } diff --git a/Shared/Tree/FeedTreeControllerDelegate.swift b/Shared/Tree/FeedTreeControllerDelegate.swift index fd7e3ccda..54c85a201 100644 --- a/Shared/Tree/FeedTreeControllerDelegate.swift +++ b/Shared/Tree/FeedTreeControllerDelegate.swift @@ -82,12 +82,12 @@ private extension FeedTreeControllerDelegate { var updatedChildNodes = [Node]() - children.forEach { (representedObject) in + for representedObject in children { if let existingNode = containerNode.childNodeRepresentingObject(representedObject) { if !updatedChildNodes.contains(existingNode) { updatedChildNodes += [existingNode] - return + continue } } diff --git a/Tree/Sources/Tree/TreeController.swift b/Tree/Sources/Tree/TreeController.swift index f124c8ebd..5855a6bab 100644 --- a/Tree/Sources/Tree/TreeController.swift +++ b/Tree/Sources/Tree/TreeController.swift @@ -89,7 +89,8 @@ private extension TreeController { func visitNode(_ node: Node, _ visitBlock: NodeVisitBlock) { visitBlock(node) - node.childNodes.forEach{ (oneChildNode) in + + for oneChildNode in node.childNodes { visitNode(oneChildNode, visitBlock) } } @@ -115,16 +116,14 @@ private extension TreeController { return false } - var childNodesDidChange = false - let childNodes = delegate?.treeController(treeController: self, childNodesFor: node) ?? [Node]() - childNodesDidChange = !nodeArraysAreEqual(childNodes, node.childNodes) - if (childNodesDidChange) { + var childNodesDidChange = !nodeArraysAreEqual(childNodes, node.childNodes) + if childNodesDidChange { node.childNodes = childNodes } - childNodes.forEach{ (oneChildNode) in + for oneChildNode in childNodes { if rebuildChildNodes(node: oneChildNode) { childNodesDidChange = true } diff --git a/Web/Sources/Web/DownloadSession.swift b/Web/Sources/Web/DownloadSession.swift index 0356241dc..2e0f01178 100755 --- a/Web/Sources/Web/DownloadSession.swift +++ b/Web/Sources/Web/DownloadSession.swift @@ -64,9 +64,15 @@ public protocol DownloadSessionDelegate { public func cancelAll() { urlSession.getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in - dataTasks.forEach { $0.cancel() } - uploadTasks.forEach { $0.cancel() } - downloadTasks.forEach { $0.cancel() } + for dataTask in dataTasks { + dataTask.cancel() + } + for uploadTask in uploadTasks { + uploadTask.cancel() + } + for downloadTask in downloadTasks { + downloadTask.cancel() + } } } diff --git a/Web/Sources/Web/HTTPLinkPagingInfo.swift b/Web/Sources/Web/HTTPLinkPagingInfo.swift index 38f4ed774..ec5be00df 100644 --- a/Web/Sources/Web/HTTPLinkPagingInfo.swift +++ b/Web/Sources/Web/HTTPLinkPagingInfo.swift @@ -28,14 +28,12 @@ public struct HTTPLinkPagingInfo { let links = linkHeader.components(separatedBy: ",") var dict: [String: String] = [:] - links.forEach({ - let components = $0.components(separatedBy:"; ") + for link in links { + let components = link.components(separatedBy:"; ") let page = components[0].trimmingCharacters(in: CharacterSet(charactersIn: " <>")) dict[components[1]] = page - }) + } self.init(nextPage: dict["rel=\"next\""], lastPage: dict["rel=\"last\""]) - } - } diff --git a/Web/Sources/Web/OneShotDownload.swift b/Web/Sources/Web/OneShotDownload.swift index 98f811fc8..6bbe0d329 100755 --- a/Web/Sources/Web/OneShotDownload.swift +++ b/Web/Sources/Web/OneShotDownload.swift @@ -88,7 +88,7 @@ private final class WebCache { func cleanup(_ cleanupInterval: TimeInterval) { let cutoffDate = Date(timeInterval: -cleanupInterval, since: Date()) - cache.keys.forEach { (key) in + for key in cache.keys { let cacheRecord = self[key]! if shouldDelete(cacheRecord, cutoffDate) { cache[key] = nil @@ -169,7 +169,7 @@ private struct CallbackRecord { } var callbackCount = 0 - self.pendingCallbacks.forEach{ (callbackRecord) in + for callbackRecord in self.pendingCallbacks { if url == callbackRecord.url { callbackRecord.completion(data, response, error) callbackCount += 1 diff --git a/Web/Sources/Web/WebServices/Transport.swift b/Web/Sources/Web/WebServices/Transport.swift index 7915953fd..fa131d518 100644 --- a/Web/Sources/Web/WebServices/Transport.swift +++ b/Web/Sources/Web/WebServices/Transport.swift @@ -142,9 +142,15 @@ extension URLSession: Transport { public func cancelAll() { getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in - dataTasks.forEach { $0.cancel() } - uploadTasks.forEach { $0.cancel() } - downloadTasks.forEach { $0.cancel() } + for dataTask in dataTasks { + dataTask.cancel() + } + for uploadTask in uploadTasks { + uploadTask.cancel() + } + for downloadTask in downloadTasks { + downloadTask.cancel() + } } } diff --git a/iOS/AppDelegate.swift b/iOS/AppDelegate.swift index a426bcdeb..805c30964 100644 --- a/iOS/AppDelegate.swift +++ b/iOS/AppDelegate.swift @@ -158,8 +158,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // MARK: - API func manualRefresh(errorHandler: @escaping (Error) -> ()) { - UIApplication.shared.connectedScenes.compactMap( { $0.delegate as? SceneDelegate } ).forEach { - $0.cleanUp(conditional: true) + + let sceneDelegates = UIApplication.shared.connectedScenes.compactMap{ $0.delegate as? SceneDelegate } + for sceneDelegate in sceneDelegates { + sceneDelegate.cleanUp(conditional: true) } Task { @MainActor in diff --git a/iOS/Feeds/SidebarViewController.swift b/iOS/Feeds/SidebarViewController.swift index 9d30add19..8fdc1e128 100644 --- a/iOS/Feeds/SidebarViewController.swift +++ b/iOS/Feeds/SidebarViewController.swift @@ -786,9 +786,9 @@ private extension SidebarViewController { } func applyToAvailableCells(_ completion: (FeedTableViewCell, IndexPath) -> Void) { - tableView.visibleCells.forEach { cell in + for cell in tableView.visibleCells { guard let indexPath = tableView.indexPath(for: cell) else { - return + continue } completion(cell as! FeedTableViewCell, indexPath) } diff --git a/iOS/Timeline/TimelineViewController.swift b/iOS/Timeline/TimelineViewController.swift index 7154db2c3..434da9c52 100644 --- a/iOS/Timeline/TimelineViewController.swift +++ b/iOS/Timeline/TimelineViewController.swift @@ -449,12 +449,15 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner { guard let feed = note.userInfo?[UserInfoKey.feed] as? Feed else { return } - tableView.indexPathsForVisibleRows?.forEach { indexPath in - guard let article = dataSource.itemIdentifier(for: indexPath) else { - return - } - if article.feed == feed, let cell = tableView.cellForRow(at: indexPath) as? TimelineTableViewCell, let image = iconImageFor(article) { - cell.setIconImage(image) + + if let indexPaths = tableView.indexPathsForVisibleRows { + for indexPath in indexPaths { + guard let article = dataSource.itemIdentifier(for: indexPath) else { + continue + } + if article.feed == feed, let cell = tableView.cellForRow(at: indexPath) as? TimelineTableViewCell, let image = iconImageFor(article) { + cell.setIconImage(image) + } } } } @@ -463,13 +466,16 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner { guard coordinator.showIcons, let avatarURL = note.userInfo?[UserInfoKey.url] as? String else { return } - tableView.indexPathsForVisibleRows?.forEach { indexPath in - guard let article = dataSource.itemIdentifier(for: indexPath), let authors = article.authors, !authors.isEmpty else { - return - } - for author in authors { - if author.avatarURL == avatarURL, let cell = tableView.cellForRow(at: indexPath) as? TimelineTableViewCell, let image = iconImageFor(article) { - cell.setIconImage(image) + + if let indexPaths = tableView.indexPathsForVisibleRows { + for indexPath in indexPaths { + guard let article = dataSource.itemIdentifier(for: indexPath), let authors = article.authors, !authors.isEmpty else { + continue + } + for author in authors { + if author.avatarURL == avatarURL, let cell = tableView.cellForRow(at: indexPath) as? TimelineTableViewCell, let image = iconImageFor(article) { + cell.setIconImage(image) + } } } } diff --git a/iOS/UIKit Extensions/Array-Extensions.swift b/iOS/UIKit Extensions/Array-Extensions.swift index 9a4710680..3b4bbe0cd 100644 --- a/iOS/UIKit Extensions/Array-Extensions.swift +++ b/iOS/UIKit Extensions/Array-Extensions.swift @@ -13,8 +13,9 @@ extension Array where Element == CGRect { func maxY() -> CGFloat { var y: CGFloat = 0.0 - self.forEach { y = Swift.max(y, $0.maxY) } + for r in self { + y = Swift.max(y, r.maxY) + } return y } - } diff --git a/iOS/UIKit Extensions/RoundedProgressView.swift b/iOS/UIKit Extensions/RoundedProgressView.swift index a48aa6bf1..5f892dcbf 100644 --- a/iOS/UIKit Extensions/RoundedProgressView.swift +++ b/iOS/UIKit Extensions/RoundedProgressView.swift @@ -12,10 +12,9 @@ class RoundedProgressView: UIProgressView { override func layoutSubviews() { super.layoutSubviews() - subviews.forEach { subview in + for subview in subviews { subview.layer.masksToBounds = true subview.layer.cornerRadius = bounds.height / 2.0 } } - }