Replace forEach for for-in.
This commit is contained in:
parent
53215c1f80
commit
6db1d40597
@ -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
|
||||
|
@ -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<FeedbinSubscription>()
|
||||
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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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?) {
|
||||
|
@ -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() {
|
||||
|
@ -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]()
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<String>) -> 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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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]()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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\""])
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user