Continue deleting completion-based functions in SyncDatabase.
This commit is contained in:
parent
4385b2d6b7
commit
951349ffc5
@ -20,38 +20,39 @@ import CloudKitExtras
|
||||
class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate {
|
||||
|
||||
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
||||
|
||||
|
||||
weak var account: Account?
|
||||
var database: SyncDatabase
|
||||
weak var articlesZone: CloudKitArticlesZone?
|
||||
var compressionQueue = DispatchQueue(label: "Articles Zone Delegate Compression Queue")
|
||||
|
||||
|
||||
init(account: Account, database: SyncDatabase, articlesZone: CloudKitArticlesZone) {
|
||||
self.account = account
|
||||
self.database = database
|
||||
self.articlesZone = articlesZone
|
||||
}
|
||||
|
||||
|
||||
func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
|
||||
database.selectPendingReadStatusArticleIDs() { result in
|
||||
switch result {
|
||||
case .success(let pendingReadStatusArticleIDs):
|
||||
|
||||
self.database.selectPendingStarredStatusArticleIDs() { result in
|
||||
switch result {
|
||||
case .success(let pendingStarredStatusArticleIDs):
|
||||
Task { @MainActor in
|
||||
|
||||
do {
|
||||
|
||||
let pendingStarredStatusArticleIDs = (try await self.database.selectPendingStarredStatusArticleIDs()) ?? Set<String>()
|
||||
self.delete(recordKeys: deleted, pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs) {
|
||||
Task { @MainActor in
|
||||
self.update(records: changed,
|
||||
pendingReadStatusArticleIDs: pendingReadStatusArticleIDs,
|
||||
pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs,
|
||||
completion: completion)
|
||||
pendingReadStatusArticleIDs: pendingReadStatusArticleIDs,
|
||||
pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs,
|
||||
completion: completion)
|
||||
}
|
||||
}
|
||||
|
||||
case .failure(let error):
|
||||
|
||||
} catch {
|
||||
os_log(.error, log: self.log, "Error occurred getting pending starred records: %@", error.localizedDescription)
|
||||
completion(.failure(CloudKitZoneError.unknown))
|
||||
}
|
||||
@ -70,12 +71,12 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
let receivedRecordIDs = recordKeys.filter({ $0.recordType == CloudKitArticlesZone.CloudKitArticleStatus.recordType }).map({ $0.recordID })
|
||||
let receivedArticleIDs = Set(receivedRecordIDs.map({ stripPrefix($0.externalID) }))
|
||||
let deletableArticleIDs = receivedArticleIDs.subtracting(pendingStarredStatusArticleIDs)
|
||||
|
||||
|
||||
guard !deletableArticleIDs.isEmpty else {
|
||||
completion()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Task { @MainActor in
|
||||
try? await self.database.deleteSelectedForProcessing(Array(deletableArticleIDs))
|
||||
self.account?.delete(articleIDs: deletableArticleIDs) { _ in
|
||||
@ -98,7 +99,7 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
|
||||
var errorOccurred = false
|
||||
let group = DispatchGroup()
|
||||
|
||||
|
||||
group.enter()
|
||||
account?.markAsUnread(updateableUnreadArticleIDs) { databaseError in
|
||||
MainActor.assumeIsolated {
|
||||
@ -147,7 +148,7 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
compressionQueue.async {
|
||||
let parsedItems = records.compactMap { self.makeParsedItem($0) }
|
||||
let feedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) }
|
||||
|
||||
|
||||
DispatchQueue.main.async {
|
||||
for (feedID, parsedItems) in feedIDsAndItems {
|
||||
group.enter()
|
||||
@ -174,7 +175,7 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
if errorOccurred {
|
||||
completion(.failure(CloudKitZoneError.unknown))
|
||||
@ -183,7 +184,7 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func stripPrefix(_ externalID: String) -> String {
|
||||
return String(externalID[externalID.index(externalID.startIndex, offsetBy: 2)..<externalID.endIndex])
|
||||
}
|
||||
@ -192,11 +193,11 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
guard articleRecord.recordType == CloudKitArticlesZone.CloudKitArticle.recordType else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var parsedAuthors = Set<ParsedAuthor>()
|
||||
|
||||
|
||||
let decoder = JSONDecoder()
|
||||
|
||||
|
||||
if let encodedParsedAuthors = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.parsedAuthors] as? [String] {
|
||||
for encodedParsedAuthor in encodedParsedAuthors {
|
||||
if let data = encodedParsedAuthor.data(using: .utf8), let parsedAuthor = try? decoder.decode(ParsedAuthor.self, from: data) {
|
||||
@ -204,26 +205,26 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
guard let uniqueID = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.uniqueID] as? String,
|
||||
let feedURL = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.feedURL] as? String else {
|
||||
let feedURL = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.feedURL] as? String else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var contentHTML = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentHTML] as? String
|
||||
if let contentHTMLData = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentHTMLData] as? NSData {
|
||||
if let decompressedContentHTMLData = try? contentHTMLData.decompressed(using: .lzfse) {
|
||||
contentHTML = String(data: decompressedContentHTMLData as Data, encoding: .utf8)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var contentText = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentText] as? String
|
||||
if let contentTextData = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentTextData] as? NSData {
|
||||
if let decompressedContentTextData = try? contentTextData.decompressed(using: .lzfse) {
|
||||
contentText = String(data: decompressedContentTextData as Data, encoding: .utf8)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let parsedItem = ParsedItem(syncServiceID: nil,
|
||||
uniqueID: uniqueID,
|
||||
feedURL: feedURL,
|
||||
@ -241,8 +242,7 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
authors: parsedAuthors,
|
||||
tags: nil,
|
||||
attachments: nil)
|
||||
|
||||
|
||||
return parsedItem
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1360,54 +1360,52 @@ private extension FeedbinAccountDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
database.selectPendingStarredStatusArticleIDs() { result in
|
||||
Task { @MainActor in
|
||||
|
||||
do {
|
||||
let pendingArticleIDs = (try await self.database.selectPendingStarredStatusArticleIDs()) ?? Set<String>()
|
||||
|
||||
MainActor.assumeIsolated {
|
||||
@MainActor func process(_ pendingArticleIDs: Set<String>) {
|
||||
|
||||
|
||||
let feedbinStarredArticleIDs = Set(articleIDs.map { String($0) } )
|
||||
let updatableFeedbinStarredArticleIDs = feedbinStarredArticleIDs.subtracting(pendingArticleIDs)
|
||||
|
||||
|
||||
account.fetchStarredArticleIDs { articleIDsResult in
|
||||
|
||||
|
||||
MainActor.assumeIsolated {
|
||||
guard let currentStarredArticleIDs = try? articleIDsResult.get() else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
|
||||
// Mark articles as starred
|
||||
let deltaStarredArticleIDs = updatableFeedbinStarredArticleIDs.subtracting(currentStarredArticleIDs)
|
||||
group.enter()
|
||||
account.markAsStarred(deltaStarredArticleIDs) { _ in
|
||||
group.leave()
|
||||
}
|
||||
|
||||
|
||||
// Mark articles as unstarred
|
||||
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(updatableFeedbinStarredArticleIDs)
|
||||
group.enter()
|
||||
account.markAsUnstarred(deltaUnstarredArticleIDs) { _ in
|
||||
group.leave()
|
||||
}
|
||||
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch result {
|
||||
case .success(let pendingArticleIDs):
|
||||
process(pendingArticleIDs)
|
||||
case .failure(let error):
|
||||
os_log(.error, log: self.log, "Sync Article Starred Status failed: %@.", error.localizedDescription)
|
||||
}
|
||||
|
||||
process(pendingArticleIDs)
|
||||
|
||||
} catch {
|
||||
os_log(.error, log: self.log, "Sync Article Starred Status failed: %@.", error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func deleteTagging(for account: Account, with feed: Feed, from container: Container?, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
@ -77,17 +77,15 @@ final class FeedlyIngestStarredArticleIdsOperation: FeedlyOperation {
|
||||
return
|
||||
}
|
||||
|
||||
database.selectPendingStarredStatusArticleIDs { result in
|
||||
MainActor.assumeIsolated {
|
||||
switch result {
|
||||
case .success(let pendingArticleIds):
|
||||
self.remoteEntryIds.subtract(pendingArticleIds)
|
||||
Task { @MainActor in
|
||||
|
||||
self.updateStarredStatuses()
|
||||
|
||||
case .failure(let error):
|
||||
self.didFinish(with: error)
|
||||
do {
|
||||
if let pendingArticleIDs = try await self.database.selectPendingStarredStatusArticleIDs() {
|
||||
self.remoteEntryIds.subtract(pendingArticleIDs)
|
||||
}
|
||||
self.updateStarredStatuses()
|
||||
} catch {
|
||||
self.didFinish(with: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,17 +78,15 @@ final class FeedlyIngestUnreadArticleIdsOperation: FeedlyOperation {
|
||||
return
|
||||
}
|
||||
|
||||
database.selectPendingReadStatusArticleIDs { result in
|
||||
MainActor.assumeIsolated {
|
||||
switch result {
|
||||
case .success(let pendingArticleIds):
|
||||
self.remoteEntryIds.subtract(pendingArticleIds)
|
||||
Task { @MainActor in
|
||||
|
||||
self.updateUnreadStatuses()
|
||||
|
||||
case .failure(let error):
|
||||
self.didFinish(with: error)
|
||||
do {
|
||||
if let pendingArticleIDs = try await self.database.selectPendingReadStatusArticleIDs() {
|
||||
self.remoteEntryIds.subtract(pendingArticleIDs)
|
||||
}
|
||||
self.updateUnreadStatuses()
|
||||
} catch {
|
||||
self.didFinish(with: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -381,8 +381,11 @@ extension NewsBlurAccountDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
database.selectPendingStarredStatusArticleIDs() { result in
|
||||
MainActor.assumeIsolated {
|
||||
Task { @MainActor in
|
||||
|
||||
do {
|
||||
let pendingArticleIDs = (try await database.selectPendingStarredStatusArticleIDs()) ?? Set<String>()
|
||||
|
||||
@MainActor func process(_ pendingStoryHashes: Set<String>) {
|
||||
|
||||
let newsBlurStarredStoryHashes = Set(hashes.map { $0.hash } )
|
||||
@ -393,23 +396,23 @@ extension NewsBlurAccountDelegate {
|
||||
guard let currentStarredArticleIDs = try? articleIDsResult.get() else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
|
||||
// Mark articles as starred
|
||||
let deltaStarredArticleIDs = updatableNewsBlurUnreadStoryHashes.subtracting(currentStarredArticleIDs)
|
||||
group.enter()
|
||||
account.markAsStarred(deltaStarredArticleIDs) { _ in
|
||||
group.leave()
|
||||
}
|
||||
|
||||
|
||||
// Mark articles as unstarred
|
||||
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(updatableNewsBlurUnreadStoryHashes)
|
||||
group.enter()
|
||||
account.markAsUnstarred(deltaUnstarredArticleIDs) { _ in
|
||||
group.leave()
|
||||
}
|
||||
|
||||
|
||||
group.notify(queue: DispatchQueue.main) {
|
||||
completion()
|
||||
}
|
||||
@ -417,12 +420,10 @@ extension NewsBlurAccountDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
switch result {
|
||||
case .success(let pendingArticleIDs):
|
||||
process(pendingArticleIDs)
|
||||
case .failure(let error):
|
||||
os_log(.error, log: self.log, "Sync Story Starred Status failed: %@.", error.localizedDescription)
|
||||
}
|
||||
process(pendingArticleIDs)
|
||||
|
||||
} catch {
|
||||
os_log(.error, log: self.log, "Sync Story Starred Status failed: %@.", error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1161,9 +1161,12 @@ private extension ReaderAPIAccountDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
database.selectPendingStarredStatusArticleIDs() { result in
|
||||
Task { @MainActor in
|
||||
|
||||
do {
|
||||
|
||||
let pendingArticleIDs = (try await self.database.selectPendingStarredStatusArticleIDs()) ?? Set<String>()
|
||||
|
||||
MainActor.assumeIsolated {
|
||||
@MainActor func process(_ pendingArticleIDs: Set<String>) {
|
||||
let updatableReaderUnreadArticleIDs = Set(articleIDs).subtracting(pendingArticleIDs)
|
||||
|
||||
@ -1197,15 +1200,11 @@ private extension ReaderAPIAccountDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
switch result {
|
||||
case .success(let pendingArticleIDs):
|
||||
process(pendingArticleIDs)
|
||||
case .failure(let error):
|
||||
os_log(.error, log: self.log, "Sync Article Starred Status failed: %@.", error.localizedDescription)
|
||||
}
|
||||
process(pendingArticleIDs)
|
||||
|
||||
} catch {
|
||||
os_log(.error, log: self.log, "Sync Article Starred Status failed: %@.", error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public actor SyncDatabase {
|
||||
return syncStatusTable.selectPendingStarredStatusArticleIDs(database: database)
|
||||
}
|
||||
|
||||
public func resetAllSelectedForProcessing() throws {
|
||||
public func resetAllSelectedForProcessing() throws {
|
||||
|
||||
guard let database else {
|
||||
throw DatabaseError.suspended
|
||||
@ -179,33 +179,6 @@ public extension SyncDatabase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated func selectPendingStarredStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
|
||||
|
||||
Task { @MainActor in
|
||||
do {
|
||||
if let articleIDs = try await self.selectPendingStarredStatusArticleIDs() {
|
||||
completion(.success(articleIDs))
|
||||
} else {
|
||||
completion(.success(Set<String>()))
|
||||
}
|
||||
} catch {
|
||||
completion(.failure(DatabaseError.suspended))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated func resetAllSelectedForProcessing(completion: DatabaseCompletionBlock? = nil) {
|
||||
|
||||
Task { @MainActor in
|
||||
do {
|
||||
try await self.resetAllSelectedForProcessing()
|
||||
completion?(nil)
|
||||
} catch {
|
||||
completion?(DatabaseError.suspended)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension SyncDatabase {
|
||||
|
Loading…
x
Reference in New Issue
Block a user