From ba0a2d352135983c6364aba0196910ec902bc96e Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Mon, 18 Nov 2024 15:11:18 -0800 Subject: [PATCH] Remove use of forEach. --- Account/Sources/Account/Account.swift | 24 +++++---- Account/Sources/Account/AccountManager.swift | 50 ++++++++++++------- .../CloudKit/CloudKitAccountZone.swift | 8 +-- .../CloudKitAccountZoneDelegate.swift | 4 +- .../Sources/Account/FeedMetadataFile.swift | 4 +- .../Feedbin/FeedbinAccountDelegate.swift | 10 ++-- ...teFeedsForCollectionFoldersOperation.swift | 2 +- .../NewsBlurAccountDelegate+Internal.swift | 8 +-- Account/Sources/Account/OPMLNormalizer.swift | 8 ++- .../ReaderAPI/ReaderAPIAccountDelegate.swift | 12 ++--- .../ArticlesDatabase/SearchTable.swift | 6 ++- .../RSCore/Shared/CoalescingQueue.swift | 4 +- .../Shared/MainThreadOperationQueue.swift | 16 ++++-- .../RSCore/Shared/UndoableCommand.swift | 6 ++- .../UIKit/UIViewController+RSCore.swift | 8 ++- .../Sources/RSDatabase/DatabaseTable.swift | 2 +- RSTree/Sources/RSTree/TreeController.swift | 4 +- RSWeb/Sources/RSWeb/DownloadSession.swift | 12 +++-- RSWeb/Sources/RSWeb/HTTPLinkPagingInfo.swift | 6 +-- RSWeb/Sources/RSWeb/OneShotDownload.swift | 4 +- .../Sources/RSWeb/WebServices/Transport.swift | 12 +++-- Shared/SmartFeeds/SmartFeed.swift | 6 ++- Shared/Timeline/FetchRequestQueue.swift | 4 +- Shared/Tree/FeedTreeControllerDelegate.swift | 4 +- iOS/Timeline/TimelineViewController.swift | 30 ++++++----- 25 files changed, 156 insertions(+), 98 deletions(-) diff --git a/Account/Sources/Account/Account.swift b/Account/Sources/Account/Account.swift index bd452173f..966f85679 100644 --- a/Account/Sources/Account/Account.swift +++ b/Account/Sources/Account/Account.swift @@ -491,9 +491,11 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } else { if let title = item.titleFromAttributes, let folder = ensureFolder(with: title) { folder.externalID = item.attributes?["nnw_externalID"] as? String - item.items?.forEach { itemChild in - if let feedSpecifier = itemChild.feedSpecifier { - folder.addFeed(newFeed(with: feedSpecifier)) + if let items = item.items { + for itemChild in items { + if let feedSpecifier = itemChild.feedSpecifier { + folder.addFeed(newFeed(with: feedSpecifier)) + } } } } @@ -521,9 +523,11 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, 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 @@ -925,7 +929,9 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, public func debugDropConditionalGetInfo() { #if DEBUG - flattenedFeeds().forEach{ $0.dropConditionalGetInfo() } + for feed in flattenedFeeds() { + feed.dropConditionalGetInfo() + } #endif } @@ -1169,7 +1175,7 @@ private extension Account { for article in articles where !article.status.read { unreadCountStorage[article.feedID, default: 0] += 1 } - feeds.forEach { (feed) in + for feed in feeds { let unreadCount = unreadCountStorage[feed.feedID, default: 0] feed.unreadCount = unreadCount } @@ -1220,7 +1226,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/AccountManager.swift b/Account/Sources/Account/AccountManager.swift index fe97c0bbc..7e9355001 100644 --- a/Account/Sources/Account/AccountManager.swift +++ b/Account/Sources/Account/AccountManager.swift @@ -215,23 +215,31 @@ public final class AccountManager: UnreadCountProvider { 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], completion: (() -> Void)? = nil) { let group = DispatchGroup() - activeAccounts.forEach { account in + for account in activeAccounts { group.enter() account.receiveRemoteNotification(userInfo: userInfo) { group.leave() @@ -248,7 +256,7 @@ public final class AccountManager: UnreadCountProvider { let group = DispatchGroup() - activeAccounts.forEach { account in + for account in activeAccounts { group.enter() account.refreshAll() { result in group.leave() @@ -272,7 +280,7 @@ public final class AccountManager: UnreadCountProvider { var syncErrors = [AccountSyncError]() let group = DispatchGroup() - activeAccounts.forEach { account in + for account in activeAccounts { group.enter() account.refreshAll() { result in group.leave() @@ -297,9 +305,9 @@ public final class AccountManager: UnreadCountProvider { public func sendArticleStatusAll(completion: (() -> Void)? = nil) { let group = DispatchGroup() - activeAccounts.forEach { + for account in activeAccounts { group.enter() - $0.sendArticleStatus() { _ in + account.sendArticleStatus() { _ in group.leave() } } @@ -312,9 +320,9 @@ public final class AccountManager: UnreadCountProvider { public func syncArticleStatusAll(completion: (() -> Void)? = nil) { let group = DispatchGroup() - activeAccounts.forEach { + for account in activeAccounts { group.enter() - $0.syncArticleStatus() { _ in + account.syncArticleStatus() { _ in group.leave() } } @@ -325,7 +333,9 @@ public final class AccountManager: UnreadCountProvider { } public func saveAll() { - accounts.forEach { $0.save() } + for account in accounts { + account.save() + } } public func anyAccountHasAtLeastOneFeed() -> Bool { @@ -481,13 +491,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/CloudKitAccountZone.swift b/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift index cf5f96ec7..02deb6d51 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift @@ -77,9 +77,11 @@ final class CloudKitAccountZone: CloudKitZone { if let title = item.titleFromAttributes { let containerRecord = newContainerCKRecord(name: title) records.append(containerRecord) - item.items?.forEach { itemChild in - if let feedSpecifier = itemChild.feedSpecifier { - processFeed(feedSpecifier: feedSpecifier, containerExternalID: containerRecord.externalID) + if let items = item.items { + for itemChild in items { + if let feedSpecifier = itemChild.feedSpecifier { + processFeed(feedSpecifier: feedSpecifier, containerExternalID: containerRecord.externalID) + } } } } diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift index 4b11514bb..b5fc40ea8 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift @@ -84,9 +84,9 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate { 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/FeedMetadataFile.swift b/Account/Sources/Account/FeedMetadataFile.swift index af05746d3..e73dbc8fd 100644 --- a/Account/Sources/Account/FeedMetadataFile.swift +++ b/Account/Sources/Account/FeedMetadataFile.swift @@ -38,7 +38,9 @@ final class FeedMetadataFile { let decoder = PropertyListDecoder() account.feedMetadata = (try? decoder.decode(Account.FeedMetadataDictionary.self, from: fileData)) ?? Account.FeedMetadataDictionary() } - account.feedMetadata.values.forEach { $0.delegate = account } + for value in account.feedMetadata.values { + value.delegate = account + } } func save() { diff --git a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift index 95588028f..0a867aa0c 100644 --- a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift @@ -761,7 +761,7 @@ 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 } @@ -779,7 +779,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) @@ -799,7 +799,7 @@ 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) } @@ -835,7 +835,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) @@ -854,7 +854,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/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift index bc13136fc..13d0d9dac 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift @@ -95,7 +95,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/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift b/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift index 7a905e7e9..893b0ba72 100644 --- a/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift +++ b/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift @@ -46,7 +46,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) @@ -67,7 +67,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) } @@ -118,8 +118,8 @@ extension NewsBlurAccountDelegate { } // Actually add feeds all in one go, so we don’t trigger various rebuilding things that Account does. - feedsToAdd.forEach { feed in - let feed = account.createFeed(with: feed.name, url: feed.feedURL, feedID: String(feed.feedID), homePageURL: feed.homePageURL) + for feedToAdd in feedsToAdd { + let feed = account.createFeed(with: feedToAdd.name, url: feedToAdd.feedURL, feedID: String(feedToAdd.feedID), homePageURL: feedToAdd.homePageURL) feed.externalID = String(feed.feedID) account.addFeed(feed) } diff --git a/Account/Sources/Account/OPMLNormalizer.swift b/Account/Sources/Account/OPMLNormalizer.swift index 2f5fa8b37..850cf1ad4 100644 --- a/Account/Sources/Account/OPMLNormalizer.swift +++ b/Account/Sources/Account/OPMLNormalizer.swift @@ -22,13 +22,13 @@ final class OPMLNormalizer { private func normalize(_ items: [OPMLItem], parentFolder: OPMLItem? = nil) { var feedsToAdd = [OPMLItem]() - 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.items { normalize(itemChildren, parentFolder: parentFolder) } - return + continue } feedsToAdd.append(item) @@ -60,7 +60,5 @@ final class OPMLNormalizer { normalizedOPMLItems.append(feed) } } - } - } diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index c7c351f27..248cfb9bb 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -718,7 +718,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) @@ -738,7 +738,7 @@ 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 @@ -775,8 +775,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 @@ -801,14 +801,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/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift index 4cf11fd35..0db68850b 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift @@ -132,7 +132,9 @@ final class SearchTable: DatabaseTable { private extension SearchTable { func performInitialIndexForArticles(_ articles: Set, _ database: FMDatabase) { - articles.forEach { performInitialIndex($0, database) } + for article in articles { + performInitialIndex(article, database) + } } func performInitialIndex(_ article: ArticleSearchInfo, _ database: FMDatabase) { @@ -177,7 +179,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/RSCore/Sources/RSCore/Shared/CoalescingQueue.swift b/RSCore/Sources/RSCore/Shared/CoalescingQueue.swift index ec2271fe0..1010576d9 100644 --- a/RSCore/Sources/RSCore/Shared/CoalescingQueue.swift +++ b/RSCore/Sources/RSCore/Shared/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/RSCore/Sources/RSCore/Shared/MainThreadOperationQueue.swift b/RSCore/Sources/RSCore/Shared/MainThreadOperationQueue.swift index be7d225dd..95b59bd0c 100644 --- a/RSCore/Sources/RSCore/Shared/MainThreadOperationQueue.swift +++ b/RSCore/Sources/RSCore/Shared/MainThreadOperationQueue.swift @@ -68,7 +68,9 @@ public final class MainThreadOperationQueue { /// Add multiple operations to the queue. /// This has the same effect as calling addOperation one-by-one. 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. @@ -453,16 +455,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 value in dependencies.values { + value.remove(operationID) + } } func removeEmptyDependencies() { diff --git a/RSCore/Sources/RSCore/Shared/UndoableCommand.swift b/RSCore/Sources/RSCore/Shared/UndoableCommand.swift index 5594151ff..5904feaea 100644 --- a/RSCore/Sources/RSCore/Shared/UndoableCommand.swift +++ b/RSCore/Sources/RSCore/Shared/UndoableCommand.swift @@ -67,10 +67,12 @@ public extension UndoableCommandRunner { // Otherwise things like Redo Mark Read are ambiguous. // (Do they apply to the previous articles or to the current articles?) - guard let undoManager = undoManager else { + guard let undoManager else { return } - undoableCommands.forEach { undoManager.removeAllActions(withTarget: $0) } + for undoableCommand in undoableCommands { + undoManager.removeAllActions(withTarget: undoableCommand) + } undoableCommands = [UndoableCommand]() } } diff --git a/RSCore/Sources/RSCore/UIKit/UIViewController+RSCore.swift b/RSCore/Sources/RSCore/UIKit/UIViewController+RSCore.swift index a4945c594..4c024d892 100644 --- a/RSCore/Sources/RSCore/UIKit/UIViewController+RSCore.swift +++ b/RSCore/Sources/RSCore/UIKit/UIViewController+RSCore.swift @@ -19,8 +19,12 @@ extension UIViewController { } public func replaceChildAndPinView(_ controller: UIViewController) { - view.subviews.forEach { $0.removeFromSuperview() } - children.forEach { $0.removeFromParent() } + for subview in view.subviews { + subview.removeFromSuperview() + } + for child in children { + child.removeFromParent() + } addChildAndPinView(controller) } diff --git a/RSDatabase/Sources/RSDatabase/DatabaseTable.swift b/RSDatabase/Sources/RSDatabase/DatabaseTable.swift index 45ad0e69c..3dc4a5707 100644 --- a/RSDatabase/Sources/RSDatabase/DatabaseTable.swift +++ b/RSDatabase/Sources/RSDatabase/DatabaseTable.swift @@ -62,7 +62,7 @@ public extension DatabaseTable { func insertRows(_ dictionaries: [DatabaseDictionary], insertType: RSDatabaseInsertType, in database: FMDatabase) { - dictionaries.forEach { (oneDictionary) in + for oneDictionary in dictionaries { let _ = database.rs_insertRow(with: oneDictionary, insertType: insertType, tableName: self.name) } } diff --git a/RSTree/Sources/RSTree/TreeController.swift b/RSTree/Sources/RSTree/TreeController.swift index 412885709..cfdaad35c 100644 --- a/RSTree/Sources/RSTree/TreeController.swift +++ b/RSTree/Sources/RSTree/TreeController.swift @@ -89,7 +89,7 @@ private extension TreeController { func visitNode(_ node: Node, _ visitBlock: NodeVisitBlock) { visitBlock(node) - node.childNodes.forEach{ (oneChildNode) in + for oneChildNode in node.childNodes { visitNode(oneChildNode, visitBlock) } } @@ -124,7 +124,7 @@ private extension TreeController { node.childNodes = childNodes } - childNodes.forEach{ (oneChildNode) in + for oneChildNode in childNodes { if rebuildChildNodes(node: oneChildNode) { childNodesDidChange = true } diff --git a/RSWeb/Sources/RSWeb/DownloadSession.swift b/RSWeb/Sources/RSWeb/DownloadSession.swift index c15edfb9e..9d95b269e 100755 --- a/RSWeb/Sources/RSWeb/DownloadSession.swift +++ b/RSWeb/Sources/RSWeb/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/RSWeb/Sources/RSWeb/HTTPLinkPagingInfo.swift b/RSWeb/Sources/RSWeb/HTTPLinkPagingInfo.swift index 38f4ed774..e63d6c9e5 100644 --- a/RSWeb/Sources/RSWeb/HTTPLinkPagingInfo.swift +++ b/RSWeb/Sources/RSWeb/HTTPLinkPagingInfo.swift @@ -28,11 +28,11 @@ 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/RSWeb/Sources/RSWeb/OneShotDownload.swift b/RSWeb/Sources/RSWeb/OneShotDownload.swift index cfe30d6d1..659dfc84b 100755 --- a/RSWeb/Sources/RSWeb/OneShotDownload.swift +++ b/RSWeb/Sources/RSWeb/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 @@ -168,7 +168,7 @@ private final class DownloadWithCacheManager { } 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/RSWeb/Sources/RSWeb/WebServices/Transport.swift b/RSWeb/Sources/RSWeb/WebServices/Transport.swift index d9d78d8ca..0705a7c28 100644 --- a/RSWeb/Sources/RSWeb/WebServices/Transport.swift +++ b/RSWeb/Sources/RSWeb/WebServices/Transport.swift @@ -134,9 +134,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/Shared/SmartFeeds/SmartFeed.swift b/Shared/SmartFeeds/SmartFeed.swift index a31473f19..ec7a65d3e 100644 --- a/Shared/SmartFeeds/SmartFeed.swift +++ b/Shared/SmartFeeds/SmartFeed.swift @@ -66,7 +66,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) } @@ -75,7 +75,9 @@ final class SmartFeed: PseudoFeed { if activeAccounts.isEmpty { updateUnreadCount() } else { - activeAccounts.forEach { self.fetchUnreadCount(for: $0) } + for account in activeAccounts { + self.fetchUnreadCount(for: account) + } } } diff --git a/Shared/Timeline/FetchRequestQueue.swift b/Shared/Timeline/FetchRequestQueue.swift index 4fd9ff093..688d5e6fd 100644 --- a/Shared/Timeline/FetchRequestQueue.swift +++ b/Shared/Timeline/FetchRequestQueue.swift @@ -24,7 +24,9 @@ final class FetchRequestQueue { 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 2edea991c..80db8cdf0 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/iOS/Timeline/TimelineViewController.swift b/iOS/Timeline/TimelineViewController.swift index 42e593bb6..08bc85e89 100644 --- a/iOS/Timeline/TimelineViewController.swift +++ b/iOS/Timeline/TimelineViewController.swift @@ -452,12 +452,14 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner { guard let feed = note.userInfo?[UserInfoKey.feed] as? Feed else { return } - for indexPath in tableView.indexPathsForVisibleRows? { - 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) + 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) + } } } } @@ -466,13 +468,15 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner { guard coordinator.showIcons, let avatarURL = note.userInfo?[UserInfoKey.url] as? String else { return } - for indexPath in tableView.indexPathsForVisibleRows? { - 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) + 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) + } } } }