Move CloudKitArticlesZone to CloudKitSync module.
This commit is contained in:
parent
60dd9ad82a
commit
55e3e20be1
@ -420,6 +420,7 @@ enum CloudKitAccountDelegateError: LocalizedError {
|
|||||||
|
|
||||||
accountZone.delegate = CloudKitAcountZoneDelegate(account: account, refreshProgress: refreshProgress, articlesZone: articlesZone)
|
accountZone.delegate = CloudKitAcountZoneDelegate(account: account, refreshProgress: refreshProgress, articlesZone: articlesZone)
|
||||||
articlesZone.delegate = CloudKitArticlesZoneDelegate(account: account, database: database, articlesZone: articlesZone)
|
articlesZone.delegate = CloudKitArticlesZoneDelegate(account: account, database: database, articlesZone: articlesZone)
|
||||||
|
articlesZone.feedInfoDelegate = self
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
try await database.resetAllSelectedForProcessing()
|
try await database.resetAllSelectedForProcessing()
|
||||||
@ -748,3 +749,16 @@ extension CloudKitAccountDelegate: LocalAccountRefresherDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension CloudKitAccountDelegate: CloudKitFeedInfoDelegate {
|
||||||
|
|
||||||
|
@MainActor func feedExternalID(article: Article) -> String? {
|
||||||
|
|
||||||
|
article.feed?.externalID
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor func feedURL(article: Article) -> String? {
|
||||||
|
|
||||||
|
article.feed?.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,8 +16,9 @@ import Articles
|
|||||||
import ArticlesDatabase
|
import ArticlesDatabase
|
||||||
import Database
|
import Database
|
||||||
import CloudKitExtras
|
import CloudKitExtras
|
||||||
|
import CloudKitSync
|
||||||
|
|
||||||
class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate {
|
final class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate {
|
||||||
|
|
||||||
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
||||||
|
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import os.log
|
import os.log
|
||||||
import Core
|
import Core
|
||||||
|
import CloudKitSync
|
||||||
|
|
||||||
class CloudKitReceiveStatusOperation: MainThreadOperation {
|
final class CloudKitReceiveStatusOperation: MainThreadOperation {
|
||||||
|
|
||||||
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
||||||
|
|
||||||
|
@ -15,58 +15,64 @@ import CloudKit
|
|||||||
import Articles
|
import Articles
|
||||||
import SyncDatabase
|
import SyncDatabase
|
||||||
import CloudKitExtras
|
import CloudKitExtras
|
||||||
import CloudKitSync
|
|
||||||
|
|
||||||
final class CloudKitArticlesZone: CloudKitZone {
|
public protocol CloudKitFeedInfoDelegate {
|
||||||
|
|
||||||
var zoneID: CKRecordZone.ID
|
@MainActor func feedExternalID(article: Article) -> String?
|
||||||
|
@MainActor func feedURL(article: Article) -> String?
|
||||||
|
}
|
||||||
|
|
||||||
var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
public final class CloudKitArticlesZone: CloudKitZone {
|
||||||
|
|
||||||
weak var container: CKContainer?
|
public var zoneID: CKRecordZone.ID
|
||||||
weak var database: CKDatabase?
|
|
||||||
var delegate: CloudKitZoneDelegate? = nil
|
public var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
||||||
|
|
||||||
|
public weak var container: CKContainer?
|
||||||
|
public weak var database: CKDatabase?
|
||||||
|
public var delegate: CloudKitZoneDelegate? = nil
|
||||||
|
public var feedInfoDelegate: CloudKitFeedInfoDelegate? = nil
|
||||||
|
|
||||||
var compressionQueue = DispatchQueue(label: "Articles Zone Compression Queue")
|
var compressionQueue = DispatchQueue(label: "Articles Zone Compression Queue")
|
||||||
|
|
||||||
struct CloudKitArticle {
|
public struct CloudKitArticle {
|
||||||
static let recordType = "Article"
|
public static let recordType = "Article"
|
||||||
struct Fields {
|
public struct Fields {
|
||||||
static let articleStatus = "articleStatus"
|
public static let articleStatus = "articleStatus"
|
||||||
static let feedURL = "webFeedURL"
|
public static let feedURL = "webFeedURL"
|
||||||
static let uniqueID = "uniqueID"
|
public static let uniqueID = "uniqueID"
|
||||||
static let title = "title"
|
public static let title = "title"
|
||||||
static let contentHTML = "contentHTML"
|
public static let contentHTML = "contentHTML"
|
||||||
static let contentHTMLData = "contentHTMLData"
|
public static let contentHTMLData = "contentHTMLData"
|
||||||
static let contentText = "contentText"
|
public static let contentText = "contentText"
|
||||||
static let contentTextData = "contentTextData"
|
public static let contentTextData = "contentTextData"
|
||||||
static let url = "url"
|
public static let url = "url"
|
||||||
static let externalURL = "externalURL"
|
public static let externalURL = "externalURL"
|
||||||
static let summary = "summary"
|
public static let summary = "summary"
|
||||||
static let imageURL = "imageURL"
|
public static let imageURL = "imageURL"
|
||||||
static let datePublished = "datePublished"
|
public static let datePublished = "datePublished"
|
||||||
static let dateModified = "dateModified"
|
public static let dateModified = "dateModified"
|
||||||
static let parsedAuthors = "parsedAuthors"
|
public static let parsedAuthors = "parsedAuthors"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CloudKitArticleStatus {
|
public struct CloudKitArticleStatus {
|
||||||
static let recordType = "ArticleStatus"
|
public static let recordType = "ArticleStatus"
|
||||||
struct Fields {
|
public struct Fields {
|
||||||
static let feedExternalID = "webFeedExternalID"
|
public static let feedExternalID = "webFeedExternalID"
|
||||||
static let read = "read"
|
public static let read = "read"
|
||||||
static let starred = "starred"
|
public static let starred = "starred"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor init(container: CKContainer) {
|
@MainActor public init(container: CKContainer) {
|
||||||
self.container = container
|
self.container = container
|
||||||
self.database = container.privateCloudDatabase
|
self.database = container.privateCloudDatabase
|
||||||
self.zoneID = CKRecordZone.ID(zoneName: "Articles", ownerName: CKCurrentUserDefaultName)
|
self.zoneID = CKRecordZone.ID(zoneName: "Articles", ownerName: CKCurrentUserDefaultName)
|
||||||
migrateChangeToken()
|
migrateChangeToken()
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor func refreshArticles(completion: @escaping ((Result<Void, Error>) -> Void)) {
|
@MainActor public func refreshArticles(completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
fetchChangesInZone() { result in
|
fetchChangesInZone() { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
@ -90,27 +96,7 @@ final class CloudKitArticlesZone: CloudKitZone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor func saveNewArticles(_ articles: Set<Article>, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
public func deleteArticles(_ feedExternalID: String) async throws {
|
||||||
guard !articles.isEmpty else {
|
|
||||||
completion(.success(()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var records = [CKRecord]()
|
|
||||||
|
|
||||||
let saveArticles = articles.filter { $0.status.read == false || $0.status.starred == true }
|
|
||||||
for saveArticle in saveArticles {
|
|
||||||
records.append(makeStatusRecord(saveArticle))
|
|
||||||
records.append(makeArticleRecord(saveArticle))
|
|
||||||
}
|
|
||||||
|
|
||||||
compressionQueue.async {
|
|
||||||
let compressedRecords = self.compressArticleRecords(records)
|
|
||||||
self.save(compressedRecords, completion: completion)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteArticles(_ feedExternalID: String) async throws {
|
|
||||||
|
|
||||||
let predicate = NSPredicate(format: "webFeedExternalID = %@", feedExternalID)
|
let predicate = NSPredicate(format: "webFeedExternalID = %@", feedExternalID)
|
||||||
let ckQuery = CKQuery(recordType: CloudKitArticleStatus.recordType, predicate: predicate)
|
let ckQuery = CKQuery(recordType: CloudKitArticleStatus.recordType, predicate: predicate)
|
||||||
@ -118,7 +104,7 @@ final class CloudKitArticlesZone: CloudKitZone {
|
|||||||
try await delete(ckQuery: ckQuery)
|
try await delete(ckQuery: ckQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor func modifyArticles(_ statusUpdates: [CloudKitArticleStatusUpdate], completion: @escaping ((Result<Void, Error>) -> Void)) {
|
@MainActor public func modifyArticles(_ statusUpdates: [CloudKitArticleStatusUpdate], completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
guard !statusUpdates.isEmpty else {
|
guard !statusUpdates.isEmpty else {
|
||||||
completion(.success(()))
|
completion(.success(()))
|
||||||
return
|
return
|
||||||
@ -200,9 +186,11 @@ private extension CloudKitArticlesZone {
|
|||||||
@MainActor func makeStatusRecord(_ article: Article) -> CKRecord {
|
@MainActor func makeStatusRecord(_ article: Article) -> CKRecord {
|
||||||
let recordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID)
|
let recordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID)
|
||||||
let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID)
|
let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID)
|
||||||
if let feedExternalID = article.feed?.externalID {
|
|
||||||
|
if let feedExternalID = feedInfoDelegate?.feedExternalID(article: article) {
|
||||||
record[CloudKitArticleStatus.Fields.feedExternalID] = feedExternalID
|
record[CloudKitArticleStatus.Fields.feedExternalID] = feedExternalID
|
||||||
}
|
}
|
||||||
|
|
||||||
record[CloudKitArticleStatus.Fields.read] = article.status.read ? "1" : "0"
|
record[CloudKitArticleStatus.Fields.read] = article.status.read ? "1" : "0"
|
||||||
record[CloudKitArticleStatus.Fields.starred] = article.status.starred ? "1" : "0"
|
record[CloudKitArticleStatus.Fields.starred] = article.status.starred ? "1" : "0"
|
||||||
return record
|
return record
|
||||||
@ -212,7 +200,7 @@ private extension CloudKitArticlesZone {
|
|||||||
let recordID = CKRecord.ID(recordName: statusID(statusUpdate.articleID), zoneID: zoneID)
|
let recordID = CKRecord.ID(recordName: statusID(statusUpdate.articleID), zoneID: zoneID)
|
||||||
let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID)
|
let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID)
|
||||||
|
|
||||||
if let feedExternalID = statusUpdate.article?.feed?.externalID {
|
if let article = statusUpdate.article, let feedExternalID = feedInfoDelegate?.feedExternalID(article: article) {
|
||||||
record[CloudKitArticleStatus.Fields.feedExternalID] = feedExternalID
|
record[CloudKitArticleStatus.Fields.feedExternalID] = feedExternalID
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +216,7 @@ private extension CloudKitArticlesZone {
|
|||||||
|
|
||||||
let articleStatusRecordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID)
|
let articleStatusRecordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID)
|
||||||
record[CloudKitArticle.Fields.articleStatus] = CKRecord.Reference(recordID: articleStatusRecordID, action: .deleteSelf)
|
record[CloudKitArticle.Fields.articleStatus] = CKRecord.Reference(recordID: articleStatusRecordID, action: .deleteSelf)
|
||||||
record[CloudKitArticle.Fields.feedURL] = article.feed?.url
|
record[CloudKitArticle.Fields.feedURL] = feedInfoDelegate?.feedURL(article: article)
|
||||||
record[CloudKitArticle.Fields.uniqueID] = article.uniqueID
|
record[CloudKitArticle.Fields.uniqueID] = article.uniqueID
|
||||||
record[CloudKitArticle.Fields.title] = article.title
|
record[CloudKitArticle.Fields.title] = article.title
|
||||||
record[CloudKitArticle.Fields.contentHTML] = article.contentHTML
|
record[CloudKitArticle.Fields.contentHTML] = article.contentHTML
|
Loading…
x
Reference in New Issue
Block a user