2020-04-01 18:46:37 +02:00
|
|
|
//
|
|
|
|
// CloudKitArticlesZoneDelegate.swift
|
|
|
|
// Account
|
|
|
|
//
|
|
|
|
// Created by Maurice Parker on 4/1/20.
|
|
|
|
// Copyright © 2020 Ranchero Software, LLC. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
import os.log
|
|
|
|
import CloudKit
|
2020-04-01 21:10:07 +02:00
|
|
|
import SyncDatabase
|
2020-04-01 18:46:37 +02:00
|
|
|
|
|
|
|
class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate {
|
2020-04-01 19:22:59 +02:00
|
|
|
|
2020-04-01 18:46:37 +02:00
|
|
|
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
|
|
|
|
|
|
|
weak var account: Account?
|
2020-04-01 21:10:07 +02:00
|
|
|
var database: SyncDatabase
|
2020-04-03 18:25:01 +02:00
|
|
|
weak var articlesZone: CloudKitArticlesZone?
|
2020-04-01 18:46:37 +02:00
|
|
|
|
2020-04-03 18:25:01 +02:00
|
|
|
init(account: Account, database: SyncDatabase, articlesZone: CloudKitArticlesZone) {
|
2020-04-01 18:46:37 +02:00
|
|
|
self.account = account
|
2020-04-01 21:10:07 +02:00
|
|
|
self.database = database
|
2020-04-03 18:25:01 +02:00
|
|
|
self.articlesZone = articlesZone
|
2020-04-01 18:46:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func cloudKitDidChange(record: CKRecord) {
|
2020-04-01 19:22:59 +02:00
|
|
|
// Process everything in the batch method
|
|
|
|
}
|
|
|
|
|
|
|
|
func cloudKitDidDelete(recordKey: CloudKitRecordKey) {
|
|
|
|
// Article downloads clean up old articles and statuses
|
|
|
|
}
|
|
|
|
|
2020-04-02 03:21:14 +02:00
|
|
|
func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result<Void, Error>) -> Void) {
|
|
|
|
|
2020-04-01 21:10:07 +02:00
|
|
|
database.selectPendingReadStatusArticleIDs() { result in
|
|
|
|
switch result {
|
|
|
|
case .success(let pendingReadStatusArticleIDs):
|
|
|
|
|
|
|
|
self.database.selectPendingStarredStatusArticleIDs() { result in
|
|
|
|
switch result {
|
|
|
|
case .success(let pendingStarredStatusArticleIDs):
|
|
|
|
|
2020-04-02 03:21:14 +02:00
|
|
|
self.process(records: changed,
|
2020-04-01 21:10:07 +02:00
|
|
|
pendingReadStatusArticleIDs: pendingReadStatusArticleIDs,
|
2020-04-02 03:21:14 +02:00
|
|
|
pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs,
|
|
|
|
completion: completion)
|
2020-04-01 21:10:07 +02:00
|
|
|
|
|
|
|
case .failure(let error):
|
|
|
|
os_log(.error, log: self.log, "Error occurred geting pending starred records: %@", error.localizedDescription)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case .failure(let error):
|
|
|
|
os_log(.error, log: self.log, "Error occurred getting pending read status records: %@", error.localizedDescription)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-04-01 18:46:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-04-01 21:10:07 +02:00
|
|
|
|
|
|
|
private extension CloudKitArticlesZoneDelegate {
|
|
|
|
|
2020-04-02 03:21:14 +02:00
|
|
|
func process(records: [CKRecord], pendingReadStatusArticleIDs: Set<String>, pendingStarredStatusArticleIDs: Set<String>, completion: @escaping (Result<Void, Error>) -> Void) {
|
2020-04-01 21:10:07 +02:00
|
|
|
|
|
|
|
let receivedUnreadArticleIDs = Set(records.filter( { $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.read] == "0" }).map({ $0.externalID }))
|
|
|
|
let receivedReadArticleIDs = Set(records.filter( { $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.read] == "1" }).map({ $0.externalID }))
|
|
|
|
let receivedUnstarredArticleIDs = Set(records.filter( { $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.starred] == "0" }).map({ $0.externalID }))
|
|
|
|
let receivedStarredArticleIDs = Set(records.filter( { $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.starred] == "1" }).map({ $0.externalID }))
|
|
|
|
|
|
|
|
let updateableUnreadArticleIDs = receivedUnreadArticleIDs.subtracting(pendingReadStatusArticleIDs)
|
|
|
|
let updateableReadArticleIDs = receivedReadArticleIDs.subtracting(pendingReadStatusArticleIDs)
|
|
|
|
let updateableUnstarredArticleIDs = receivedUnstarredArticleIDs.subtracting(pendingStarredStatusArticleIDs)
|
|
|
|
let updateableStarredArticleIDs = receivedStarredArticleIDs.subtracting(pendingStarredStatusArticleIDs)
|
|
|
|
|
2020-04-02 03:21:14 +02:00
|
|
|
let group = DispatchGroup()
|
|
|
|
|
|
|
|
group.enter()
|
|
|
|
account?.markAsUnread(updateableUnreadArticleIDs) { _ in
|
|
|
|
group.leave()
|
|
|
|
}
|
|
|
|
|
|
|
|
group.enter()
|
|
|
|
account?.markAsRead(updateableReadArticleIDs) { _ in
|
|
|
|
group.leave()
|
|
|
|
}
|
|
|
|
|
|
|
|
group.enter()
|
|
|
|
account?.markAsUnstarred(updateableUnstarredArticleIDs) { _ in
|
|
|
|
group.leave()
|
|
|
|
}
|
|
|
|
|
|
|
|
group.enter()
|
|
|
|
account?.markAsStarred(updateableStarredArticleIDs) { _ in
|
|
|
|
group.leave()
|
|
|
|
}
|
2020-04-03 18:25:01 +02:00
|
|
|
|
|
|
|
for updateableStarredArticleID in updateableStarredArticleIDs {
|
|
|
|
|
|
|
|
group.enter()
|
|
|
|
articlesZone?.fetchArticle(articleID: updateableStarredArticleID) { result in
|
|
|
|
switch result {
|
|
|
|
case .success(let (webFeedID, parsedItem)):
|
|
|
|
self.account?.update(webFeedID, with: Set([parsedItem])) { databaseError in
|
|
|
|
group.leave()
|
|
|
|
if let databaseError = databaseError {
|
|
|
|
os_log(.error, log: self.log, "Error occurred while storing starred items: %@", databaseError.localizedDescription)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case .failure(let error):
|
|
|
|
group.leave()
|
|
|
|
os_log(.error, log: self.log, "Error occurred while retrieving starred items: %@", error.localizedDescription)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2020-04-02 03:21:14 +02:00
|
|
|
|
|
|
|
group.notify(queue: DispatchQueue.main) {
|
|
|
|
completion(.success(()))
|
|
|
|
}
|
2020-04-01 21:10:07 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|