diff --git a/Account/Package.swift b/Account/Package.swift
index 2f556c766..3d49c12e0 100644
--- a/Account/Package.swift
+++ b/Account/Package.swift
@@ -12,9 +12,9 @@ let package = Package(
     ],
     dependencies: [
 		.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-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/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/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<WebFeed> { 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<String> { 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<OAuthAuthorizationGrant, Error>) -> ())
 }
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<ParsedItem> { 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<FeedlyFeedsSearchResponse, Error>) -> ())
 }
 
-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<String>, 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<FeedlyStream, Error>) -> ())
 }
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<FeedlyStreamIds, Error>) -> ())
 }
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<String>, as action: FeedlyMarkAction, completion: @escaping (Result<Void, Error>) -> ())
 }
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/ArticlesDatabase/Package.swift b/ArticlesDatabase/Package.swift
index 200fd6137..6a9076bba 100644
--- a/ArticlesDatabase/Package.swift
+++ b/ArticlesDatabase/Package.swift
@@ -14,8 +14,8 @@ let package = Package(
     ],
     dependencies: [
 		.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-beta1")),
-		.package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.0-beta1")),
+		.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 099f626a1..61c2845ef 100644
--- a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift
+++ b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift
@@ -145,36 +145,19 @@ 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<String>, in database: FMDatabase) -> Set<ArticleSearchInfo>? {
 		let parameters = articleIDs.map { $0 as AnyObject }
 		let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
-        if let resultSet = database.executeQuery(self.articleSearchInfosQuery(with: placeholders), withArgumentsIn: parameters) {
+		let sql = "select articleID, title, contentHTML, contentText, summary, searchRowID from articles where articleID in \(placeholders);";
+
+		if let resultSet = database.executeQuery(sql, 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
@@ -182,7 +165,7 @@ final class ArticlesTable: DatabaseTable {
 					searchRowID = Int(row.longLongInt(forColumn: DatabaseKey.searchRowID))
 				}
 
-				return ArticleSearchInfo(articleID: articleID, title: title, authorsNames: authorsNames, contentHTML: contentHTML, contentText: contentText, summary: summary, searchRowID: searchRowID)
+				return ArticleSearchInfo(articleID: articleID, title: title, contentHTML: contentHTML, contentText: contentText, summary: summary, searchRowID: searchRowID)
 			}
 		}
 		return nil
diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift
index 100eabd3f..15bcb0cdd 100644
--- a/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift
+++ b/ArticlesDatabase/Sources/ArticlesDatabase/SearchTable.swift
@@ -17,7 +17,6 @@ final class ArticleSearchInfo: Hashable {
 
 	let articleID: String
 	let title: String?
-    let authorsNames: String?
 	let contentHTML: String?
 	let contentText: String?
 	let summary: String?
@@ -44,10 +43,9 @@ final class ArticleSearchInfo: Hashable {
         }
 	}()
 
-    init(articleID: String, title: String?, authorsNames: String?, contentHTML: String?, contentText: String?, summary: String?, searchRowID: Int?) {
+	init(articleID: String, title: String?, contentHTML: String?, contentText: String?, summary: String?, searchRowID: Int?) {
 		self.articleID = articleID
 		self.title = title
-        self.authorsNames = authorsNames
 		self.contentHTML = contentHTML
 		self.contentText = contentText
 		self.summary = summary
@@ -55,8 +53,8 @@ final class ArticleSearchInfo: Hashable {
 	}
 
 	convenience init(article: Article) {
-        let authorsNames = article.authors?.map({ $0.name }).reduce("", { $0.appending("").appending($1 ?? "") }).collapsingWhitespace
-        self.init(articleID: article.articleID, title: article.title, authorsNames: authorsNames, contentHTML: article.contentHTML, contentText: article.contentText, summary: article.summary, searchRowID: nil)
+    let authorsNames = article.authors?.map({ $0.name }).reduce("", { $0.appending("").appending($1 ?? "") }).collapsingWhitespace
+    self.init(articleID: article.articleID, title: article.title, authorsNames: authorsNames, contentHTML: article.contentHTML, contentText: article.contentText, summary: article.summary, searchRowID: nil)
 	}
 
 	// MARK: Hashable
@@ -68,7 +66,7 @@ final class ArticleSearchInfo: Hashable {
 	// MARK: Equatable
 
 	static func == (lhs: ArticleSearchInfo, rhs: ArticleSearchInfo) -> Bool {
-        return lhs.articleID == rhs.articleID && lhs.title == rhs.title && lhs.authorsNames == rhs.authorsNames && 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.searchRowID == rhs.searchRowID
 	}
 }
 
@@ -136,7 +134,7 @@ private extension SearchTable {
 	}
 
 	func insert(_ article: ArticleSearchInfo, _ database: FMDatabase) -> Int {
-        let rowDictionary: DatabaseDictionary = [DatabaseKey.body: article.bodyForIndex, DatabaseKey.title: article.title ?? ""]
+		let rowDictionary: DatabaseDictionary = [DatabaseKey.body: article.bodyForIndex, DatabaseKey.title: article.title ?? ""]
 		insertRow(rowDictionary, insertType: .normal, in: database)
 		return Int(database.lastInsertRowId())
 	}
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/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/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 f33474265..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" */ = {
@@ -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 1d7ad5d1a..0ca6b48cc 100644
--- a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -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/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/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)
 }