diff --git a/Account/Package.swift b/Account/Package.swift index 8a53ae40e..3d49c12e0 100644 --- a/Account/Package.swift +++ b/Account/Package.swift @@ -11,10 +11,10 @@ let package = Package( targets: ["Account"]), ], dependencies: [ - .package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0-beta1")), - .package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0-beta1")), - .package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0-beta1")), - .package(url: "https://github.com/Ranchero-Software/RSWeb.git", .upToNextMajor(from: "1.0.0-beta1")), + .package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0")), + .package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0")), + .package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0")), + .package(url: "https://github.com/Ranchero-Software/RSWeb.git", .upToNextMajor(from: "1.0.0")), .package(url: "../Articles", .upToNextMajor(from: "1.0.0")), .package(url: "../ArticlesDatabase", .upToNextMajor(from: "1.0.0")), .package(url: "../Secrets", .upToNextMajor(from: "1.0.0")), diff --git a/Account/Sources/Account/AccountMetadata.swift b/Account/Sources/Account/AccountMetadata.swift index f4c1a2cdb..4fa08063a 100644 --- a/Account/Sources/Account/AccountMetadata.swift +++ b/Account/Sources/Account/AccountMetadata.swift @@ -9,7 +9,7 @@ import Foundation import RSWeb -protocol AccountMetadataDelegate: class { +protocol AccountMetadataDelegate: AnyObject { func valueDidChange(_ accountMetadata: AccountMetadata, key: AccountMetadata.CodingKeys) } diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift b/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift index e0a45e0cb..64c99794f 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift @@ -21,9 +21,7 @@ enum CloudKitAccountZoneError: LocalizedError { } final class CloudKitAccountZone: CloudKitZone { - static var zoneID: CKRecordZone.ID { - return CKRecordZone.ID(zoneName: "Account", ownerName: CKCurrentUserDefaultName) - } + var zoneID: CKRecordZone.ID var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit") @@ -53,6 +51,8 @@ final class CloudKitAccountZone: CloudKitZone { init(container: CKContainer) { self.container = container self.database = container.privateCloudDatabase + self.zoneID = CKRecordZone.ID(zoneName: "Account", ownerName: CKCurrentUserDefaultName) + migrateChangeToken() } func importOPML(rootExternalID: String, items: [RSOPMLItem], completion: @escaping (Result) -> Void) { @@ -91,7 +91,7 @@ final class CloudKitAccountZone: CloudKitZone { /// Persist a web feed record to iCloud and return the external key func createWebFeed(url: String, name: String?, editedName: String?, homePageURL: String?, container: Container, completion: @escaping (Result) -> Void) { - let recordID = CKRecord.ID(recordName: url.md5String, zoneID: Self.zoneID) + let recordID = CKRecord.ID(recordName: url.md5String, zoneID: zoneID) let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID) record[CloudKitWebFeed.Fields.url] = url record[CloudKitWebFeed.Fields.name] = name @@ -125,7 +125,7 @@ final class CloudKitAccountZone: CloudKitZone { return } - let recordID = CKRecord.ID(recordName: externalID, zoneID: Self.zoneID) + let recordID = CKRecord.ID(recordName: externalID, zoneID: zoneID) let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID) record[CloudKitWebFeed.Fields.editedName] = editedName @@ -252,7 +252,7 @@ final class CloudKitAccountZone: CloudKitZone { let predicate = NSPredicate(format: "isAccount = \"1\"") let ckQuery = CKQuery(recordType: CloudKitContainer.recordType, predicate: predicate) - database?.perform(ckQuery, inZoneWith: Self.zoneID) { [weak self] records, error in + database?.perform(ckQuery, inZoneWith: zoneID) { [weak self] records, error in guard let self = self else { return } switch CloudKitZoneResult.resolve(error) { @@ -296,7 +296,7 @@ final class CloudKitAccountZone: CloudKitZone { return } - let recordID = CKRecord.ID(recordName: externalID, zoneID: Self.zoneID) + let recordID = CKRecord.ID(recordName: externalID, zoneID: zoneID) let record = CKRecord(recordType: CloudKitContainer.recordType, recordID: recordID) record[CloudKitContainer.Fields.name] = name diff --git a/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift b/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift index f085654ab..095ddcdea 100644 --- a/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift +++ b/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift @@ -17,9 +17,7 @@ import SyncDatabase final class CloudKitArticlesZone: CloudKitZone { - static var zoneID: CKRecordZone.ID { - return CKRecordZone.ID(zoneName: "Articles", ownerName: CKCurrentUserDefaultName) - } + var zoneID: CKRecordZone.ID var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit") @@ -58,6 +56,8 @@ final class CloudKitArticlesZone: CloudKitZone { init(container: CKContainer) { self.container = container self.database = container.privateCloudDatabase + self.zoneID = CKRecordZone.ID(zoneName: "Articles", ownerName: CKCurrentUserDefaultName) + migrateChangeToken() } func refreshArticles(completion: @escaping ((Result) -> Void)) { @@ -124,10 +124,10 @@ final class CloudKitArticlesZone: CloudKitZone { newRecords.append(self.makeStatusRecord(statusUpdate)) newRecords.append(self.makeArticleRecord(statusUpdate.article!)) case .delete: - deleteRecordIDs.append(CKRecord.ID(recordName: self.statusID(statusUpdate.articleID), zoneID: Self.zoneID)) + deleteRecordIDs.append(CKRecord.ID(recordName: self.statusID(statusUpdate.articleID), zoneID: zoneID)) case .statusOnly: modifyRecords.append(self.makeStatusRecord(statusUpdate)) - deleteRecordIDs.append(CKRecord.ID(recordName: self.articleID(statusUpdate.articleID), zoneID: Self.zoneID)) + deleteRecordIDs.append(CKRecord.ID(recordName: self.articleID(statusUpdate.articleID), zoneID: zoneID)) } } @@ -176,7 +176,7 @@ private extension CloudKitArticlesZone { } func makeStatusRecord(_ article: Article) -> CKRecord { - let recordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: Self.zoneID) + let recordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID) let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID) if let webFeedExternalID = article.webFeed?.externalID { record[CloudKitArticleStatus.Fields.webFeedExternalID] = webFeedExternalID @@ -187,7 +187,7 @@ private extension CloudKitArticlesZone { } func makeStatusRecord(_ statusUpdate: CloudKitArticleStatusUpdate) -> CKRecord { - let recordID = CKRecord.ID(recordName: statusID(statusUpdate.articleID), zoneID: Self.zoneID) + let recordID = CKRecord.ID(recordName: statusID(statusUpdate.articleID), zoneID: zoneID) let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID) if let webFeedExternalID = statusUpdate.article?.webFeed?.externalID { @@ -201,10 +201,10 @@ private extension CloudKitArticlesZone { } func makeArticleRecord(_ article: Article) -> CKRecord { - let recordID = CKRecord.ID(recordName: articleID(article.articleID), zoneID: Self.zoneID) + let recordID = CKRecord.ID(recordName: articleID(article.articleID), zoneID: zoneID) let record = CKRecord(recordType: CloudKitArticle.recordType, recordID: recordID) - let articleStatusRecordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: Self.zoneID) + let articleStatusRecordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID) record[CloudKitArticle.Fields.articleStatus] = CKRecord.Reference(recordID: articleStatusRecordID, action: .deleteSelf) record[CloudKitArticle.Fields.webFeedURL] = article.webFeed?.url record[CloudKitArticle.Fields.uniqueID] = article.uniqueID diff --git a/Account/Sources/Account/Container.swift b/Account/Sources/Account/Container.swift index 7c4eda9c8..1a17158ee 100644 --- a/Account/Sources/Account/Container.swift +++ b/Account/Sources/Account/Container.swift @@ -16,7 +16,7 @@ extension Notification.Name { public static let ChildrenDidChange = Notification.Name("ChildrenDidChange") } -public protocol Container: class, ContainerIdentifiable { +public protocol Container: AnyObject, ContainerIdentifiable { var account: Account? { get } var topLevelWebFeeds: Set { get set } diff --git a/Account/Sources/Account/FeedProvider/FeedProviderManager.swift b/Account/Sources/Account/FeedProvider/FeedProviderManager.swift index 4177f550c..f4b6e1cf4 100644 --- a/Account/Sources/Account/FeedProvider/FeedProviderManager.swift +++ b/Account/Sources/Account/FeedProvider/FeedProviderManager.swift @@ -8,7 +8,7 @@ import Foundation -public protocol FeedProviderManagerDelegate: class { +public protocol FeedProviderManagerDelegate: AnyObject { var activeFeedProviders: [FeedProvider] { get } } diff --git a/Account/Sources/Account/FeedProvider/Reddit/RedditFeedProviderTokenRefreshOperation.swift b/Account/Sources/Account/FeedProvider/Reddit/RedditFeedProviderTokenRefreshOperation.swift index 1b2b6bc73..6a90e9984 100644 --- a/Account/Sources/Account/FeedProvider/Reddit/RedditFeedProviderTokenRefreshOperation.swift +++ b/Account/Sources/Account/FeedProvider/Reddit/RedditFeedProviderTokenRefreshOperation.swift @@ -11,7 +11,7 @@ import RSCore import OAuthSwift import Secrets -protocol RedditFeedProviderTokenRefreshOperationDelegate: class { +protocol RedditFeedProviderTokenRefreshOperationDelegate: AnyObject { var username: String? { get } var oauthTokenLastRefresh: Date? { get set } var oauthToken: String { get set } diff --git a/Account/Sources/Account/Feedly/FeedlyAPICaller.swift b/Account/Sources/Account/Feedly/FeedlyAPICaller.swift index 36f974835..635bbe0bc 100644 --- a/Account/Sources/Account/Feedly/FeedlyAPICaller.swift +++ b/Account/Sources/Account/Feedly/FeedlyAPICaller.swift @@ -10,7 +10,7 @@ import Foundation import RSWeb import Secrets -protocol FeedlyAPICallerDelegate: class { +protocol FeedlyAPICallerDelegate: AnyObject { /// Implemented by the `FeedlyAccountDelegate` reauthorize the client with a fresh OAuth token so the client can retry the unauthorized request. /// Pass `true` to the completion handler if the failing request should be retried with a fresh token or `false` if the unauthorized request should complete with the original failure error. func reauthorizeFeedlyAPICaller(_ caller: FeedlyAPICaller, completionHandler: @escaping (Bool) -> ()) diff --git a/Account/Sources/Account/Feedly/Models/FeedlyEntryIdentifierProviding.swift b/Account/Sources/Account/Feedly/Models/FeedlyEntryIdentifierProviding.swift index 4ad0054ec..a87fbc4ea 100644 --- a/Account/Sources/Account/Feedly/Models/FeedlyEntryIdentifierProviding.swift +++ b/Account/Sources/Account/Feedly/Models/FeedlyEntryIdentifierProviding.swift @@ -8,7 +8,7 @@ import Foundation -protocol FeedlyEntryIdentifierProviding: class { +protocol FeedlyEntryIdentifierProviding: AnyObject { var entryIds: Set { get } } diff --git a/Account/Sources/Account/Feedly/OAuthAccountAuthorizationOperation.swift b/Account/Sources/Account/Feedly/OAuthAccountAuthorizationOperation.swift index 4378bedc5..f16029ce8 100644 --- a/Account/Sources/Account/Feedly/OAuthAccountAuthorizationOperation.swift +++ b/Account/Sources/Account/Feedly/OAuthAccountAuthorizationOperation.swift @@ -10,7 +10,7 @@ import Foundation import AuthenticationServices import RSCore -public protocol OAuthAccountAuthorizationOperationDelegate: class { +public protocol OAuthAccountAuthorizationOperationDelegate: AnyObject { func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didCreate account: Account) func oauthAccountAuthorizationOperation(_ operation: OAuthAccountAuthorizationOperation, didFailWith error: Error) } diff --git a/Account/Sources/Account/Feedly/OAuthAcessTokenRefreshing.swift b/Account/Sources/Account/Feedly/OAuthAcessTokenRefreshing.swift index f7b862375..d464ee405 100644 --- a/Account/Sources/Account/Feedly/OAuthAcessTokenRefreshing.swift +++ b/Account/Sources/Account/Feedly/OAuthAcessTokenRefreshing.swift @@ -40,7 +40,7 @@ public protocol OAuthAcessTokenRefreshRequesting { } /// Implemented by concrete types to perform the actual request. -protocol OAuthAccessTokenRefreshing: class { +protocol OAuthAccessTokenRefreshing: AnyObject { func refreshAccessToken(with refreshToken: String, client: OAuthAuthorizationClient, completion: @escaping (Result) -> ()) } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyCheckpointOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyCheckpointOperation.swift index d577abeae..5d32d76ec 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyCheckpointOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyCheckpointOperation.swift @@ -8,7 +8,7 @@ import Foundation -protocol FeedlyCheckpointOperationDelegate: class { +protocol FeedlyCheckpointOperationDelegate: AnyObject { func feedlyCheckpointOperationDidReachCheckpoint(_ operation: FeedlyCheckpointOperation) } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyGetCollectionsOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyGetCollectionsOperation.swift index 8477bb910..151fc2e28 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyGetCollectionsOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyGetCollectionsOperation.swift @@ -9,7 +9,7 @@ import Foundation import os.log -protocol FeedlyCollectionProviding: class { +protocol FeedlyCollectionProviding: AnyObject { var collections: [FeedlyCollection] { get } } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyGetStreamContentsOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyGetStreamContentsOperation.swift index 4c67bcfd4..7cdde6576 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyGetStreamContentsOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyGetStreamContentsOperation.swift @@ -19,7 +19,7 @@ protocol FeedlyParsedItemProviding { var parsedEntries: Set { get } } -protocol FeedlyGetStreamContentsOperationDelegate: class { +protocol FeedlyGetStreamContentsOperationDelegate: AnyObject { func feedlyGetStreamContentsOperation(_ operation: FeedlyGetStreamContentsOperation, didGetContentsOf stream: FeedlyStream) } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyGetStreamIdsOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyGetStreamIdsOperation.swift index 4f6fea202..602520720 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyGetStreamIdsOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyGetStreamIdsOperation.swift @@ -9,7 +9,7 @@ import Foundation import os.log -protocol FeedlyGetStreamIdsOperationDelegate: class { +protocol FeedlyGetStreamIdsOperationDelegate: AnyObject { func feedlyGetStreamIdsOperation(_ operation: FeedlyGetStreamIdsOperation, didGet streamIds: FeedlyStreamIds) } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyOperation.swift index e25ae63b0..a4d1c0ff1 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyOperation.swift @@ -10,7 +10,7 @@ import Foundation import RSWeb import RSCore -protocol FeedlyOperationDelegate: class { +protocol FeedlyOperationDelegate: AnyObject { func feedlyOperation(_ operation: FeedlyOperation, didFailWith error: Error) } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyRequestStreamsOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyRequestStreamsOperation.swift index 0cb7731ef..688546abb 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyRequestStreamsOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyRequestStreamsOperation.swift @@ -9,7 +9,7 @@ import Foundation import os.log -protocol FeedlyRequestStreamsOperationDelegate: class { +protocol FeedlyRequestStreamsOperationDelegate: AnyObject { func feedlyRequestStreamsOperation(_ operation: FeedlyRequestStreamsOperation, enqueue collectionStreamOperation: FeedlyGetStreamContentsOperation) } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlySearchOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlySearchOperation.swift index 5e9bfde85..40d6c76ec 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlySearchOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlySearchOperation.swift @@ -8,11 +8,11 @@ import Foundation -protocol FeedlySearchService: class { +protocol FeedlySearchService: AnyObject { func getFeeds(for query: String, count: Int, locale: String, completion: @escaping (Result) -> ()) } -protocol FeedlySearchOperationDelegate: class { +protocol FeedlySearchOperationDelegate: AnyObject { func feedlySearchOperation(_ operation: FeedlySearchOperation, didGet response: FeedlyFeedsSearchResponse) } diff --git a/Account/Sources/Account/Feedly/Services/FeedlyGetCollectionsService.swift b/Account/Sources/Account/Feedly/Services/FeedlyGetCollectionsService.swift index 5714e63c5..2dbf6861b 100644 --- a/Account/Sources/Account/Feedly/Services/FeedlyGetCollectionsService.swift +++ b/Account/Sources/Account/Feedly/Services/FeedlyGetCollectionsService.swift @@ -8,6 +8,6 @@ import Foundation -protocol FeedlyGetCollectionsService: class { +protocol FeedlyGetCollectionsService: AnyObject { func getCollections(completion: @escaping (Result<[FeedlyCollection], Error>) -> ()) } diff --git a/Account/Sources/Account/Feedly/Services/FeedlyGetEntriesService.swift b/Account/Sources/Account/Feedly/Services/FeedlyGetEntriesService.swift index 5acc75663..7bc00b607 100644 --- a/Account/Sources/Account/Feedly/Services/FeedlyGetEntriesService.swift +++ b/Account/Sources/Account/Feedly/Services/FeedlyGetEntriesService.swift @@ -8,6 +8,6 @@ import Foundation -protocol FeedlyGetEntriesService: class { +protocol FeedlyGetEntriesService: AnyObject { func getEntries(for ids: Set, completion: @escaping (Result<[FeedlyEntry], Error>) -> ()) } diff --git a/Account/Sources/Account/Feedly/Services/FeedlyGetStreamContentsService.swift b/Account/Sources/Account/Feedly/Services/FeedlyGetStreamContentsService.swift index ce80d59dc..6770a2593 100644 --- a/Account/Sources/Account/Feedly/Services/FeedlyGetStreamContentsService.swift +++ b/Account/Sources/Account/Feedly/Services/FeedlyGetStreamContentsService.swift @@ -8,6 +8,6 @@ import Foundation -protocol FeedlyGetStreamContentsService: class { +protocol FeedlyGetStreamContentsService: AnyObject { func getStreamContents(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result) -> ()) } diff --git a/Account/Sources/Account/Feedly/Services/FeedlyGetStreamIdsService.swift b/Account/Sources/Account/Feedly/Services/FeedlyGetStreamIdsService.swift index c5889cbe1..3d5863e0d 100644 --- a/Account/Sources/Account/Feedly/Services/FeedlyGetStreamIdsService.swift +++ b/Account/Sources/Account/Feedly/Services/FeedlyGetStreamIdsService.swift @@ -8,6 +8,6 @@ import Foundation -protocol FeedlyGetStreamIdsService: class { +protocol FeedlyGetStreamIdsService: AnyObject { func getStreamIds(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result) -> ()) } diff --git a/Account/Sources/Account/Feedly/Services/FeedlyMarkArticlesService.swift b/Account/Sources/Account/Feedly/Services/FeedlyMarkArticlesService.swift index 6220d147c..60a9263c2 100644 --- a/Account/Sources/Account/Feedly/Services/FeedlyMarkArticlesService.swift +++ b/Account/Sources/Account/Feedly/Services/FeedlyMarkArticlesService.swift @@ -30,6 +30,6 @@ enum FeedlyMarkAction: String { } } -protocol FeedlyMarkArticlesService: class { +protocol FeedlyMarkArticlesService: AnyObject { func mark(_ articleIds: Set, as action: FeedlyMarkAction, completion: @escaping (Result) -> ()) } diff --git a/Account/Sources/Account/WebFeedMetadata.swift b/Account/Sources/Account/WebFeedMetadata.swift index 3c2b2ed46..aa381709f 100644 --- a/Account/Sources/Account/WebFeedMetadata.swift +++ b/Account/Sources/Account/WebFeedMetadata.swift @@ -10,7 +10,7 @@ import Foundation import RSWeb import Articles -protocol WebFeedMetadataDelegate: class { +protocol WebFeedMetadataDelegate: AnyObject { func valueDidChange(_ feedMetadata: WebFeedMetadata, key: WebFeedMetadata.CodingKeys) } diff --git a/Account/Tests/AccountTests/TestTransport.swift b/Account/Tests/AccountTests/TestTransport.swift index 330d0ea37..d6070ef35 100644 --- a/Account/Tests/AccountTests/TestTransport.swift +++ b/Account/Tests/AccountTests/TestTransport.swift @@ -10,7 +10,7 @@ import Foundation import RSWeb import XCTest -protocol TestTransportMockResponseProviding: class { +protocol TestTransportMockResponseProviding: AnyObject { func mockResponseFileUrl(for components: URLComponents) -> URL? } diff --git a/Articles/Package.swift b/Articles/Package.swift index 9a996999d..d5353dc79 100644 --- a/Articles/Package.swift +++ b/Articles/Package.swift @@ -11,7 +11,7 @@ let package = Package( targets: ["Articles"]), ], dependencies: [ - .package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0-beta1")), + .package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0")), ], targets: [ .target( diff --git a/ArticlesDatabase/Package.swift b/ArticlesDatabase/Package.swift index a8d1df496..6a9076bba 100644 --- a/ArticlesDatabase/Package.swift +++ b/ArticlesDatabase/Package.swift @@ -13,9 +13,9 @@ let package = Package( targets: ["ArticlesDatabase"]), ], dependencies: [ - .package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0-beta1")), - .package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0-beta1")), - .package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0-beta1")), + .package(url: "https://github.com/Ranchero-Software/RSCore.git", .upToNextMajor(from: "1.0.0")), + .package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0")), + .package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0")), .package(url: "../Articles", .upToNextMajor(from: "1.0.0")), ], targets: [ diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift index 61c2845ef..c495f08aa 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift @@ -145,19 +145,36 @@ final class ArticlesTable: DatabaseTable { } // MARK: - Fetching Articles for Indexer + private func articleSearchInfosQuery(with placeholders: String) -> String { + return """ + SELECT + art.articleID, + art.title, + art.contentHTML, + art.contentText, + art.summary, + art.searchRowID, + (SELECT GROUP_CONCAT(name, ' ') + FROM authorsLookup as autL + JOIN authors as aut ON autL.authorID = aut.authorID + WHERE art.articleID = autL.articleID + GROUP BY autl.articleID) as authors + FROM articles as art + WHERE articleID in \(placeholders); + """ + } func fetchArticleSearchInfos(_ articleIDs: Set, in database: FMDatabase) -> Set? { let parameters = articleIDs.map { $0 as AnyObject } let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))! - let sql = "select articleID, title, contentHTML, contentText, summary, searchRowID from articles where articleID in \(placeholders);"; - - if let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) { + if let resultSet = database.executeQuery(self.articleSearchInfosQuery(with: placeholders), withArgumentsIn: parameters) { return resultSet.mapToSet { (row) -> ArticleSearchInfo? in let articleID = row.string(forColumn: DatabaseKey.articleID)! let title = row.string(forColumn: DatabaseKey.title) let contentHTML = row.string(forColumn: DatabaseKey.contentHTML) let contentText = row.string(forColumn: DatabaseKey.contentText) let summary = row.string(forColumn: DatabaseKey.summary) + let authorsNames = row.string(forColumn: DatabaseKey.authors) let searchRowIDObject = row.object(forColumnName: DatabaseKey.searchRowID) var searchRowID: Int? = nil @@ -165,7 +182,7 @@ final class ArticlesTable: DatabaseTable { searchRowID = Int(row.longLongInt(forColumn: DatabaseKey.searchRowID)) } - return ArticleSearchInfo(articleID: articleID, title: title, contentHTML: contentHTML, contentText: contentText, summary: summary, searchRowID: searchRowID) + return ArticleSearchInfo(articleID: articleID, title: title, contentHTML: contentHTML, contentText: contentText, summary: summary, authorsNames: authorsNames, searchRowID: searchRowID) } } return nil diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift index 9f97a6d69..ed08439f4 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift @@ -20,6 +20,7 @@ final class ArticleSearchInfo: Hashable { let contentHTML: String? let contentText: String? let summary: String? + let authorsNames: String? let searchRowID: Int? var preferredText: String { @@ -34,12 +35,19 @@ final class ArticleSearchInfo: Hashable { lazy var bodyForIndex: String = { let s = preferredText.rsparser_stringByDecodingHTMLEntities() - return s.strippingHTML().collapsingWhitespace + let sanitizedBody = s.strippingHTML().collapsingWhitespace + + if let authorsNames = authorsNames { + return sanitizedBody.appending(" \(authorsNames)") + } else { + return sanitizedBody + } }() - init(articleID: String, title: String?, contentHTML: String?, contentText: String?, summary: String?, searchRowID: Int?) { + init(articleID: String, title: String?, contentHTML: String?, contentText: String?, summary: String?, authorsNames: String?, searchRowID: Int?) { self.articleID = articleID self.title = title + self.authorsNames = authorsNames self.contentHTML = contentHTML self.contentText = contentText self.summary = summary @@ -47,7 +55,13 @@ final class ArticleSearchInfo: Hashable { } convenience init(article: Article) { - self.init(articleID: article.articleID, title: article.title, contentHTML: article.contentHTML, contentText: article.contentText, summary: article.summary, searchRowID: nil) + let authorsNames: String? + if let authors = article.authors { + authorsNames = authors.compactMap({ $0.name }).joined(separator: " ") + } else { + authorsNames = nil + } + self.init(articleID: article.articleID, title: article.title, contentHTML: article.contentHTML, contentText: article.contentText, summary: article.summary, authorsNames: authorsNames, searchRowID: nil) } // MARK: Hashable @@ -59,7 +73,7 @@ final class ArticleSearchInfo: Hashable { // MARK: Equatable static func == (lhs: ArticleSearchInfo, rhs: ArticleSearchInfo) -> Bool { - return lhs.articleID == rhs.articleID && lhs.title == rhs.title && lhs.contentHTML == rhs.contentHTML && lhs.contentText == rhs.contentText && lhs.summary == rhs.summary && lhs.searchRowID == rhs.searchRowID + return lhs.articleID == rhs.articleID && lhs.title == rhs.title && lhs.contentHTML == rhs.contentHTML && lhs.contentText == rhs.contentText && lhs.summary == rhs.summary && lhs.authorsNames == rhs.authorsNames && lhs.searchRowID == rhs.searchRowID } } diff --git a/Mac/Inspector/InspectorWindowController.swift b/Mac/Inspector/InspectorWindowController.swift index 8f4f82e8f..2686f86c4 100644 --- a/Mac/Inspector/InspectorWindowController.swift +++ b/Mac/Inspector/InspectorWindowController.swift @@ -8,7 +8,7 @@ import AppKit -protocol Inspector: class { +protocol Inspector: AnyObject { var objects: [Any]? { get set } var isFallbackInspector: Bool { get } // Can handle nothing-to-inspect or unexpected type of objects. diff --git a/Mac/MainWindow/AddFeed/AddFeedWIndowController.swift b/Mac/MainWindow/AddFeed/AddFeedWIndowController.swift index cbeddaa55..1651ec79f 100644 --- a/Mac/MainWindow/AddFeed/AddFeedWIndowController.swift +++ b/Mac/MainWindow/AddFeed/AddFeedWIndowController.swift @@ -15,7 +15,7 @@ enum AddFeedWindowControllerType { case twitterFeed } -protocol AddFeedWindowControllerDelegate: class { +protocol AddFeedWindowControllerDelegate: AnyObject { // userEnteredURL will have already been validated and normalized. func addFeedWindowController(_: AddFeedWindowController, userEnteredURL: URL, userEnteredTitle: String?, container: Container) diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index b1f8de853..7e71cfff1 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -12,7 +12,7 @@ import RSCore import RSWeb import Articles -protocol DetailWebViewControllerDelegate: class { +protocol DetailWebViewControllerDelegate: AnyObject { func mouseDidEnter(_: DetailWebViewController, link: String) func mouseDidExit(_: DetailWebViewController, link: String) } diff --git a/Mac/MainWindow/MainWindowController.swift b/Mac/MainWindow/MainWindowController.swift index 0c911b99f..bdacce4db 100644 --- a/Mac/MainWindow/MainWindowController.swift +++ b/Mac/MainWindow/MainWindowController.swift @@ -62,14 +62,12 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { sharingServicePickerDelegate = SharingServicePickerDelegate(self.window) if #available(macOS 11.0, *) { - DispatchQueue.main.async { - let toolbar = NSToolbar(identifier: "MainWindowToolbar") - toolbar.allowsUserCustomization = true - toolbar.autosavesConfiguration = true - toolbar.displayMode = .iconOnly - toolbar.delegate = self - self.window?.toolbar = toolbar - } + let toolbar = NSToolbar(identifier: "MainWindowToolbar") + toolbar.allowsUserCustomization = true + toolbar.autosavesConfiguration = true + toolbar.displayMode = .iconOnly + toolbar.delegate = self + self.window?.toolbar = toolbar } else { if !AppDefaults.shared.showTitleOnMainWindow { window?.titleVisibility = .hidden diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift index 11ad9399f..f403d8b25 100644 --- a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift +++ b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift @@ -490,10 +490,8 @@ private extension SidebarOutlineDataSource { return } - BatchUpdate.shared.start() replicateFolder(sourceFolder, destinationAccount: destinationAccount) { sourceAccount.removeFolder(sourceFolder) { result in - BatchUpdate.shared.end() switch result { case .success: break diff --git a/Mac/MainWindow/Sidebar/SidebarViewController.swift b/Mac/MainWindow/Sidebar/SidebarViewController.swift index 277be185e..ab9b4ac0c 100644 --- a/Mac/MainWindow/Sidebar/SidebarViewController.swift +++ b/Mac/MainWindow/Sidebar/SidebarViewController.swift @@ -16,7 +16,7 @@ extension Notification.Name { static let appleSideBarDefaultIconSizeChanged = Notification.Name("AppleSideBarDefaultIconSizeChanged") } -protocol SidebarDelegate: class { +protocol SidebarDelegate: AnyObject { func sidebarSelectionDidChange(_: SidebarViewController, selectedObjects: [AnyObject]?) func unreadCount(for: AnyObject) -> Int func sidebarInvalidatedRestorationState(_: SidebarViewController) diff --git a/Mac/MainWindow/Timeline/TimelineContainerViewController.swift b/Mac/MainWindow/Timeline/TimelineContainerViewController.swift index b43b210fd..c697a1a0c 100644 --- a/Mac/MainWindow/Timeline/TimelineContainerViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineContainerViewController.swift @@ -10,7 +10,7 @@ import AppKit import Account import Articles -protocol TimelineContainerViewControllerDelegate: class { +protocol TimelineContainerViewControllerDelegate: AnyObject { func timelineSelectionDidChange(_: TimelineContainerViewController, articles: [Article]?, mode: TimelineSourceMode) func timelineRequestedWebFeedSelection(_: TimelineContainerViewController, webFeed: WebFeed) func timelineInvalidatedRestorationState(_: TimelineContainerViewController) diff --git a/Mac/MainWindow/Timeline/TimelineViewController.swift b/Mac/MainWindow/Timeline/TimelineViewController.swift index 115a921f9..a664ffc7a 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController.swift @@ -12,7 +12,7 @@ import Articles import Account import os.log -protocol TimelineDelegate: class { +protocol TimelineDelegate: AnyObject { func timelineSelectionDidChange(_: TimelineViewController, selectedArticles: [Article]?) func timelineRequestedWebFeedSelection(_: TimelineViewController, webFeed: WebFeed) func timelineInvalidatedRestorationState(_: TimelineViewController) diff --git a/Mac/Preferences/Accounts/AccountsAddCloudKit.xib b/Mac/Preferences/Accounts/AccountsAddCloudKit.xib index 2d43d8cb4..0e286f444 100644 --- a/Mac/Preferences/Accounts/AccountsAddCloudKit.xib +++ b/Mac/Preferences/Accounts/AccountsAddCloudKit.xib @@ -1,8 +1,8 @@ - + - + @@ -18,7 +18,7 @@ - + @@ -92,7 +92,7 @@ Gw - + diff --git a/Mac/Preferences/Accounts/AccountsAddLocal.xib b/Mac/Preferences/Accounts/AccountsAddLocal.xib index 36e5232cf..35a7d35cf 100644 --- a/Mac/Preferences/Accounts/AccountsAddLocal.xib +++ b/Mac/Preferences/Accounts/AccountsAddLocal.xib @@ -1,8 +1,8 @@ - + - + @@ -19,7 +19,7 @@ - + @@ -31,7 +31,10 @@ - - - - + @@ -197,20 +197,21 @@ Gw - - + + - + + @@ -225,7 +226,7 @@ Gw - + diff --git a/Mac/Preferences/Accounts/AccountsNewsBlur.xib b/Mac/Preferences/Accounts/AccountsNewsBlur.xib index b6133daa2..c098cffc3 100644 --- a/Mac/Preferences/Accounts/AccountsNewsBlur.xib +++ b/Mac/Preferences/Accounts/AccountsNewsBlur.xib @@ -1,8 +1,8 @@ - + - + @@ -26,7 +26,7 @@ - + @@ -97,8 +97,11 @@ - @@ -224,7 +225,7 @@ Gw - + diff --git a/Mac/Preferences/Accounts/AccountsReaderAPI.xib b/Mac/Preferences/Accounts/AccountsReaderAPI.xib index 57c7be46c..46b81d5b3 100644 --- a/Mac/Preferences/Accounts/AccountsReaderAPI.xib +++ b/Mac/Preferences/Accounts/AccountsReaderAPI.xib @@ -1,8 +1,8 @@ - + - + @@ -29,17 +29,17 @@ - - + + - + - + - + @@ -125,8 +125,11 @@ - + @@ -208,10 +211,7 @@ Gw - - - - + @@ -232,15 +232,16 @@ Gw - + + - - + - + + @@ -250,7 +251,7 @@ Gw - + diff --git a/Mac/Preferences/Accounts/AddAccountsView.swift b/Mac/Preferences/Accounts/AddAccountsView.swift index eedc1131c..1eefa3d4b 100644 --- a/Mac/Preferences/Accounts/AddAccountsView.swift +++ b/Mac/Preferences/Accounts/AddAccountsView.swift @@ -101,7 +101,7 @@ struct AddAccountsView: View { parent?.dismiss(nil) }, label: { Text("Cancel") - .frame(width: 80) + .frame(width: 76) }) .help("Cancel") .keyboardShortcut(.cancelAction) @@ -111,7 +111,7 @@ struct AddAccountsView: View { parent?.dismiss(nil) }, label: { Text("Cancel") - .frame(width: 80) + .frame(width: 76) }) .accessibility(label: Text("Add Account")) } @@ -121,7 +121,7 @@ struct AddAccountsView: View { parent?.dismiss(nil) }, label: { Text("Continue") - .frame(width: 80) + .frame(width: 76) }) .help("Add Account") .keyboardShortcut(.defaultAction) @@ -132,7 +132,7 @@ struct AddAccountsView: View { parent?.dismiss(nil) }, label: { Text("Continue") - .frame(width: 80) + .frame(width: 76) }) } } diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift index 24ca1b742..d79525d30 100644 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift +++ b/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift @@ -12,7 +12,7 @@ import AuthenticationServices import OAuthSwift import Secrets -protocol ExtensionPointPreferencesEnabler: class { +protocol ExtensionPointPreferencesEnabler: AnyObject { func enable(_ extensionPointType: ExtensionPoint.Type) } diff --git a/Multiplatform/Shared/Sidebar/SidebarModel.swift b/Multiplatform/Shared/Sidebar/SidebarModel.swift index a7f87b52e..da8e36de7 100644 --- a/Multiplatform/Shared/Sidebar/SidebarModel.swift +++ b/Multiplatform/Shared/Sidebar/SidebarModel.swift @@ -12,7 +12,7 @@ import RSCore import Account import Articles -protocol SidebarModelDelegate: class { +protocol SidebarModelDelegate: AnyObject { func unreadCount(for: Feed) -> Int } diff --git a/Multiplatform/Shared/Timeline/TimelineModel.swift b/Multiplatform/Shared/Timeline/TimelineModel.swift index b96e5422a..a70cd6c69 100644 --- a/Multiplatform/Shared/Timeline/TimelineModel.swift +++ b/Multiplatform/Shared/Timeline/TimelineModel.swift @@ -16,7 +16,7 @@ import RSCore import Account import Articles -protocol TimelineModelDelegate: class { +protocol TimelineModelDelegate: AnyObject { var selectedFeedsPublisher: AnyPublisher<[Feed], Never>? { get } func timelineRequestedWebFeedSelection(_: TimelineModel, webFeed: WebFeed) } diff --git a/Multiplatform/iOS/Article/WebViewController.swift b/Multiplatform/iOS/Article/WebViewController.swift index 18d8c44c4..5e5364d54 100644 --- a/Multiplatform/iOS/Article/WebViewController.swift +++ b/Multiplatform/iOS/Article/WebViewController.swift @@ -14,7 +14,7 @@ import Articles import SafariServices import MessageUI -protocol WebViewControllerDelegate: class { +protocol WebViewControllerDelegate: AnyObject { func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState) } diff --git a/Multiplatform/macOS/Article/WebViewController.swift b/Multiplatform/macOS/Article/WebViewController.swift index b415f71d2..e71c7ef1d 100644 --- a/Multiplatform/macOS/Article/WebViewController.swift +++ b/Multiplatform/macOS/Article/WebViewController.swift @@ -11,7 +11,7 @@ import Combine import RSCore import Articles -protocol WebViewControllerDelegate: class { +protocol WebViewControllerDelegate: AnyObject { func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState) } diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index e262a739b..55c04659d 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -6095,8 +6095,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/Ranchero-Software/Sparkle-Binary.git"; requirement = { - branch = main; - kind = branch; + kind = upToNextMajorVersion; + minimumVersion = 2.0.0; }; }; 5102AE4324D17E820050839C /* XCRemoteSwiftPackageReference "RSCore" */ = { @@ -6104,7 +6104,7 @@ repositoryURL = "https://github.com/Ranchero-Software/RSCore.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = "1.0.0-beta1"; + minimumVersion = 1.0.0; }; }; 510ECA4024D1DCD0001C31A6 /* XCRemoteSwiftPackageReference "RSTree" */ = { @@ -6112,7 +6112,7 @@ repositoryURL = "https://github.com/Ranchero-Software/RSTree.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = "1.0.0-beta1"; + minimumVersion = 1.0.0; }; }; 51383A3024D1F90E0027E272 /* XCRemoteSwiftPackageReference "RSWeb" */ = { @@ -6136,7 +6136,7 @@ repositoryURL = "https://github.com/Ranchero-Software/RSDatabase.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = "1.0.0-beta1"; + minimumVersion = 1.0.0; }; }; 51B0DF2324D2C7FA000AD99E /* XCRemoteSwiftPackageReference "RSParser" */ = { @@ -6144,7 +6144,7 @@ repositoryURL = "https://github.com/Ranchero-Software/RSParser.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = "2.0.0-beta1"; + minimumVersion = 2.0.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3f40017d1..71a837402 100644 --- a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -60,8 +60,8 @@ "repositoryURL": "https://github.com/Ranchero-Software/RSCore.git", "state": { "branch": null, - "revision": "dce76a4070ed24f148bb1673c308962dbdbf01ef", - "version": "1.0.0-beta9" + "revision": "6b2ef2580968905af825c40442dc0ba3126032c0", + "version": "1.0.2" } }, { @@ -69,8 +69,8 @@ "repositoryURL": "https://github.com/Ranchero-Software/RSDatabase.git", "state": { "branch": null, - "revision": "3aa706f3adfc0b798a2b69cf536461c39db4d269", - "version": "1.0.0-beta1" + "revision": "a6c5f1622320f745cc9a0a910d1bed1e2eaf15e3", + "version": "1.0.0" } }, { @@ -78,8 +78,8 @@ "repositoryURL": "https://github.com/Ranchero-Software/RSParser.git", "state": { "branch": null, - "revision": "fd9b9c974d551a9c94d970da90a42571d234efd6", - "version": "2.0.0-beta4" + "revision": "a4467cb6ab32d67fa8b09fcef8b234c7f96b7f9c", + "version": "2.0.0" } }, { @@ -87,8 +87,8 @@ "repositoryURL": "https://github.com/Ranchero-Software/RSTree.git", "state": { "branch": null, - "revision": "979ed0eb610b6d95dc7adcf4620bd44205f512a6", - "version": "1.0.0-beta1" + "revision": "9d051f42cfc4faa991fd79cdb32e4cc8c545e334", + "version": "1.0.0" } }, { @@ -104,9 +104,9 @@ "package": "RSSparkle", "repositoryURL": "https://github.com/Ranchero-Software/Sparkle-Binary.git", "state": { - "branch": "main", + "branch": null, "revision": "67cd26321bdf4e77954cf6de7d9e6a20544f2030", - "version": null + "version": "2.0.0" } }, { diff --git a/Shared/SmartFeeds/PseudoFeed.swift b/Shared/SmartFeeds/PseudoFeed.swift index 622e1b32f..2d49603f2 100644 --- a/Shared/SmartFeeds/PseudoFeed.swift +++ b/Shared/SmartFeeds/PseudoFeed.swift @@ -13,7 +13,7 @@ import Articles import Account import RSCore -protocol PseudoFeed: class, Feed, SmallIconProvider, PasteboardWriterOwner { +protocol PseudoFeed: AnyObject, Feed, SmallIconProvider, PasteboardWriterOwner { } @@ -24,7 +24,7 @@ import Articles import Account import RSCore -protocol PseudoFeed: class, Feed, SmallIconProvider { +protocol PseudoFeed: AnyObject, Feed, SmallIconProvider { } diff --git a/Shared/UserNotifications/UserNotificationManager.swift b/Shared/UserNotifications/UserNotificationManager.swift index edb0d07d0..d8ed11eeb 100644 --- a/Shared/UserNotifications/UserNotificationManager.swift +++ b/Shared/UserNotifications/UserNotificationManager.swift @@ -33,10 +33,10 @@ final class UserNotificationManager: NSObject { } @objc func statusesDidChange(_ note: Notification) { - guard let articleIDs = note.userInfo?[Account.UserInfoKey.articleIDs] as? Set, !articleIDs.isEmpty else { + guard let statuses = note.userInfo?[Account.UserInfoKey.statuses] as? Set, !statuses.isEmpty else { return } - let identifiers = articleIDs.map { "articleID:\($0)" } + let identifiers = statuses.filter({ $0.read }).map { "articleID:\($0.articleID)" } UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiers) } diff --git a/SyncDatabase/Package.swift b/SyncDatabase/Package.swift index b78824b86..ae85d01d1 100644 --- a/SyncDatabase/Package.swift +++ b/SyncDatabase/Package.swift @@ -11,7 +11,7 @@ let package = Package( targets: ["SyncDatabase"]), ], dependencies: [ - .package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0-beta1")), + .package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0")), .package(url: "../Articles", .upToNextMajor(from: "1.0.0")), ], targets: [ diff --git a/iOS/Article/WebViewController.swift b/iOS/Article/WebViewController.swift index 6024d02dd..e00898eb5 100644 --- a/iOS/Article/WebViewController.swift +++ b/iOS/Article/WebViewController.swift @@ -14,7 +14,7 @@ import Articles import SafariServices import MessageUI -protocol WebViewControllerDelegate: class { +protocol WebViewControllerDelegate: AnyObject { func webViewController(_: WebViewController, articleExtractorButtonStateDidUpdate: ArticleExtractorButtonState) } diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift index 8bb30a720..4cb6f90e6 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift @@ -11,7 +11,7 @@ import RSCore import Account import RSTree -protocol MasterFeedTableViewCellDelegate: class { +protocol MasterFeedTableViewCellDelegate: AnyObject { func masterFeedTableViewCellDisclosureDidToggle(_ sender: MasterFeedTableViewCell, expanding: Bool) } diff --git a/iOS/MasterTimeline/MasterTimelineViewController.swift b/iOS/MasterTimeline/MasterTimelineViewController.swift index d92638b33..27462c202 100644 --- a/iOS/MasterTimeline/MasterTimelineViewController.swift +++ b/iOS/MasterTimeline/MasterTimelineViewController.swift @@ -471,13 +471,15 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner } @objc func userDefaultsDidChange(_ note: Notification) { - if numberOfTextLines != AppDefaults.shared.timelineNumberOfLines || iconSize != AppDefaults.shared.timelineIconSize { - numberOfTextLines = AppDefaults.shared.timelineNumberOfLines - iconSize = AppDefaults.shared.timelineIconSize - resetEstimatedRowHeight() - reloadAllVisibleCells() + DispatchQueue.main.async { + if self.numberOfTextLines != AppDefaults.shared.timelineNumberOfLines || self.iconSize != AppDefaults.shared.timelineIconSize { + self.numberOfTextLines = AppDefaults.shared.timelineNumberOfLines + self.iconSize = AppDefaults.shared.timelineIconSize + self.resetEstimatedRowHeight() + self.reloadAllVisibleCells() + } + self.updateToolbar() } - updateToolbar() } @objc func contentSizeCategoryDidChange(_ note: Notification) { diff --git a/iOS/ShareExtension/ShareFolderPickerController.swift b/iOS/ShareExtension/ShareFolderPickerController.swift index d70fcf332..3d957974b 100644 --- a/iOS/ShareExtension/ShareFolderPickerController.swift +++ b/iOS/ShareExtension/ShareFolderPickerController.swift @@ -10,7 +10,7 @@ import UIKit import Account import RSCore -protocol ShareFolderPickerControllerDelegate: class { +protocol ShareFolderPickerControllerDelegate: AnyObject { func shareFolderPickerDidSelect(_ container: ExtensionContainer) }