mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Switch back to having separate article and status records
This commit is contained in:
@@ -120,13 +120,15 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
||||
self.articlesZone.modifyArticles(statusedArticles) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
self.database.deleteSelectedForProcessing(syncStatuses.map({ $0.articleID }) )
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
completion(.success(()))
|
||||
self.database.deleteSelectedForProcessing(syncStatuses.map({ $0.articleID })) { _ in
|
||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||
completion(.success(()))
|
||||
}
|
||||
case .failure(let error):
|
||||
self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID }) )
|
||||
self.processAccountError(account, error)
|
||||
completion(.failure(error))
|
||||
self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID })) { _ in
|
||||
self.processAccountError(account, error)
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||
struct CloudKitArticle {
|
||||
static let recordType = "Article"
|
||||
struct Fields {
|
||||
static let hollow = "hollow"
|
||||
static let articleStatus = "articleStatus"
|
||||
static let webFeedURL = "webFeedURL"
|
||||
static let uniqueID = "uniqueID"
|
||||
static let title = "title"
|
||||
@@ -42,6 +42,13 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||
static let datePublished = "datePublished"
|
||||
static let dateModified = "dateModified"
|
||||
static let parsedAuthors = "parsedAuthors"
|
||||
}
|
||||
}
|
||||
|
||||
struct CloudKitArticleStatus {
|
||||
static let recordType = "ArticleStatus"
|
||||
struct Fields {
|
||||
static let webFeedExternalID = "webFeedExternalID"
|
||||
static let read = "read"
|
||||
static let starred = "starred"
|
||||
}
|
||||
@@ -109,21 +116,20 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||
for statusArticle in statusArticles {
|
||||
switch (statusArticle.status.key, statusArticle.status.flag) {
|
||||
case (.new, true):
|
||||
// create status
|
||||
newRecords.append(makeStatusRecord(statusArticle))
|
||||
if let article = statusArticle.article {
|
||||
newRecords.append(contentsOf: makeArticleRecords(article))
|
||||
}
|
||||
case (.starred, true), (.read, false):
|
||||
// create status
|
||||
modifyRecords.append(makeStatusRecord(statusArticle))
|
||||
if let article = statusArticle.article {
|
||||
modifyRecords.append(contentsOf: makeArticleRecords(article))
|
||||
}
|
||||
case (.deleted, true):
|
||||
deleteRecordIDs.append(CKRecord.ID(recordName: statusArticle.status.articleID, zoneID: Self.zoneID))
|
||||
deleteRecordIDs.append(CKRecord.ID(recordName: statusID(statusArticle.status.articleID), zoneID: Self.zoneID))
|
||||
default:
|
||||
print()
|
||||
// create status
|
||||
// delete article record
|
||||
modifyRecords.append(makeStatusRecord(statusArticle))
|
||||
deleteRecordIDs.append(CKRecord.ID(recordName: statusID(statusArticle.status.articleID), zoneID: Self.zoneID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,14 +168,49 @@ private extension CloudKitArticlesZone {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
func statusID(_ id: String) -> String {
|
||||
return "s|\(id)"
|
||||
}
|
||||
|
||||
func articleID(_ id: String) -> String {
|
||||
return "a|\(id)"
|
||||
}
|
||||
|
||||
func makeStatusRecord(_ statusArticle: (status: SyncStatus, article: Article?)) -> CKRecord {
|
||||
let status = statusArticle.status
|
||||
let recordID = CKRecord.ID(recordName: statusID(status.articleID), zoneID: Self.zoneID)
|
||||
let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID)
|
||||
|
||||
if let webFeedExternalID = statusArticle.article?.webFeed?.externalID {
|
||||
record[CloudKitArticleStatus.Fields.webFeedExternalID] = webFeedExternalID
|
||||
}
|
||||
|
||||
if let article = statusArticle.article {
|
||||
record[CloudKitArticleStatus.Fields.read] = article.status.read ? "1" : "0"
|
||||
record[CloudKitArticleStatus.Fields.starred] = article.status.starred ? "1" : "0"
|
||||
} else {
|
||||
switch status.key {
|
||||
case .read:
|
||||
record[CloudKitArticleStatus.Fields.read] = status.flag ? "1" : "0"
|
||||
case .starred:
|
||||
record[CloudKitArticleStatus.Fields.starred] = status.flag ? "1" : "0"
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return record
|
||||
}
|
||||
|
||||
func makeArticleRecords(_ article: Article) -> [CKRecord] {
|
||||
var records = [CKRecord]()
|
||||
|
||||
let recordID = CKRecord.ID(recordName: article.articleID, zoneID: Self.zoneID)
|
||||
let recordID = CKRecord.ID(recordName: articleID(article.articleID), zoneID: Self.zoneID)
|
||||
let articleRecord = CKRecord(recordType: CloudKitArticle.recordType, recordID: recordID)
|
||||
|
||||
articleRecord[CloudKitArticle.Fields.hollow] = "0"
|
||||
let articleStatusRecordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: Self.zoneID)
|
||||
articleRecord[CloudKitArticle.Fields.articleStatus] = CKRecord.Reference(recordID: articleStatusRecordID, action: .deleteSelf)
|
||||
articleRecord[CloudKitArticle.Fields.webFeedURL] = article.webFeed?.url
|
||||
articleRecord[CloudKitArticle.Fields.uniqueID] = article.uniqueID
|
||||
articleRecord[CloudKitArticle.Fields.title] = article.title
|
||||
@@ -198,37 +239,9 @@ private extension CloudKitArticlesZone {
|
||||
articleRecord[CloudKitArticle.Fields.parsedAuthors] = parsedAuthors
|
||||
}
|
||||
|
||||
articleRecord[CloudKitArticle.Fields.read] = article.status.read ? "1" : "0"
|
||||
articleRecord[CloudKitArticle.Fields.starred] = article.status.starred ? "1" : "0"
|
||||
|
||||
records.append(articleRecord)
|
||||
return records
|
||||
}
|
||||
|
||||
func makeHollowArticleRecords(_ article: Article) -> [CKRecord] {
|
||||
var records = [CKRecord]()
|
||||
|
||||
let recordID = CKRecord.ID(recordName: article.articleID, zoneID: Self.zoneID)
|
||||
let articleRecord = CKRecord(recordType: CloudKitArticle.recordType, recordID: recordID)
|
||||
|
||||
articleRecord[CloudKitArticle.Fields.hollow] = "1"
|
||||
articleRecord[CloudKitArticle.Fields.webFeedURL] = article.webFeed?.url
|
||||
articleRecord[CloudKitArticle.Fields.uniqueID] = nil
|
||||
articleRecord[CloudKitArticle.Fields.title] = nil
|
||||
articleRecord[CloudKitArticle.Fields.contentHTML] = nil
|
||||
articleRecord[CloudKitArticle.Fields.contentText] = nil
|
||||
articleRecord[CloudKitArticle.Fields.url] = nil
|
||||
articleRecord[CloudKitArticle.Fields.externalURL] = nil
|
||||
articleRecord[CloudKitArticle.Fields.summary] = nil
|
||||
articleRecord[CloudKitArticle.Fields.imageURL] = nil
|
||||
articleRecord[CloudKitArticle.Fields.datePublished] = nil
|
||||
articleRecord[CloudKitArticle.Fields.dateModified] = nil
|
||||
articleRecord[CloudKitArticle.Fields.parsedAuthors] = nil
|
||||
articleRecord[CloudKitArticle.Fields.read] = article.status.read ? "1" : "0"
|
||||
articleRecord[CloudKitArticle.Fields.starred] = article.status.starred ? "1" : "0"
|
||||
|
||||
records.append(articleRecord)
|
||||
return records
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
|
||||
func process(records: [CKRecord], pendingReadStatusArticleIDs: Set<String>, pendingStarredStatusArticleIDs: Set<String>, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
let receivedUnreadArticleIDs = Set(records.filter({ $0[CloudKitArticlesZone.CloudKitArticle.Fields.read] == "0" }).map({ $0.externalID }))
|
||||
let receivedReadArticleIDs = Set(records.filter({ $0[CloudKitArticlesZone.CloudKitArticle.Fields.read] == "1" }).map({ $0.externalID }))
|
||||
let receivedUnstarredArticleIDs = Set(records.filter({ $0[CloudKitArticlesZone.CloudKitArticle.Fields.starred] == "0" }).map({ $0.externalID }))
|
||||
let receivedStarredArticleIDs = Set(records.filter({ $0[CloudKitArticlesZone.CloudKitArticle.Fields.starred] == "1" }).map({ $0.externalID }))
|
||||
let receivedUnreadArticleIDs = Set(records.filter({ $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.read] == "0" }).map({ stripPrefix($0.externalID) }))
|
||||
let receivedReadArticleIDs = Set(records.filter({ $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.read] == "1" }).map({ stripPrefix($0.externalID) }))
|
||||
let receivedUnstarredArticleIDs = Set(records.filter({ $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.starred] == "0" }).map({ stripPrefix($0.externalID) }))
|
||||
let receivedStarredArticleIDs = Set(records.filter({ $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.starred] == "1" }).map({ stripPrefix($0.externalID) }))
|
||||
|
||||
let updateableUnreadArticleIDs = receivedUnreadArticleIDs.subtracting(pendingReadStatusArticleIDs)
|
||||
let updateableReadArticleIDs = receivedReadArticleIDs.subtracting(pendingReadStatusArticleIDs)
|
||||
@@ -110,9 +110,13 @@ private extension CloudKitArticlesZoneDelegate {
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
|
||||
func stripPrefix(_ externalID: String) -> String {
|
||||
return String(externalID[externalID.index(externalID.startIndex, offsetBy: 2)..<externalID.endIndex])
|
||||
}
|
||||
|
||||
func makeParsedItem(_ articleRecord: CKRecord) -> ParsedItem? {
|
||||
guard articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.hollow] as? String ?? "0" == "0" else {
|
||||
guard articleRecord.recordType == CloudKitArticlesZone.CloudKitArticle.recordType else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user