Save starred articles to iCloud.
This commit is contained in:
parent
f97194b9be
commit
d6b094b37e
|
@ -86,17 +86,34 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.articlesZone.sendArticleStatus(syncStatuses) { result in
|
let starredArticleIDs = syncStatuses.filter({ $0.key == .starred && $0.flag == true }).map({ $0.articleID })
|
||||||
switch result {
|
account.fetchArticlesAsync(.articleIDs(Set(starredArticleIDs))) { result in
|
||||||
case .success:
|
|
||||||
self.database.deleteSelectedForProcessing(syncStatuses.map({ $0.articleID }) )
|
func processWithArticles(_ starredArticles: Set<Article>) {
|
||||||
os_log(.debug, log: self.log, "Done sending article statuses.")
|
|
||||||
completion(.success(()))
|
self.articlesZone.sendArticleStatus(syncStatuses, starredArticles: starredArticles) { result in
|
||||||
case .failure(let error):
|
switch result {
|
||||||
self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID }) )
|
case .success:
|
||||||
completion(.failure(error))
|
self.database.deleteSelectedForProcessing(syncStatuses.map({ $0.articleID }) )
|
||||||
|
os_log(.debug, log: self.log, "Done sending article statuses.")
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
self.database.resetSelectedForProcessing(syncStatuses.map({ $0.articleID }) )
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success(let starredArticles):
|
||||||
|
processWithArticles(starredArticles)
|
||||||
|
case .failure(let databaseError):
|
||||||
|
completion(.failure(databaseError))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import Foundation
|
||||||
import os.log
|
import os.log
|
||||||
import RSWeb
|
import RSWeb
|
||||||
import CloudKit
|
import CloudKit
|
||||||
|
import Articles
|
||||||
import SyncDatabase
|
import SyncDatabase
|
||||||
|
|
||||||
final class CloudKitArticlesZone: CloudKitZone {
|
final class CloudKitArticlesZone: CloudKitZone {
|
||||||
|
@ -24,6 +25,37 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||||
weak var database: CKDatabase?
|
weak var database: CKDatabase?
|
||||||
var delegate: CloudKitZoneDelegate? = nil
|
var delegate: CloudKitZoneDelegate? = nil
|
||||||
|
|
||||||
|
struct CloudKitArticle {
|
||||||
|
static let recordType = "Article"
|
||||||
|
struct Fields {
|
||||||
|
static let articleStatus = "articleStatus"
|
||||||
|
static let webFeedID = "webFeedID"
|
||||||
|
static let uniqueID = "uniqueID"
|
||||||
|
static let title = "title"
|
||||||
|
static let contentHTML = "contentHTML"
|
||||||
|
static let contentText = "contentText"
|
||||||
|
static let url = "url"
|
||||||
|
static let externalURL = "externalURL"
|
||||||
|
static let summary = "summary"
|
||||||
|
static let imageURL = "imageURL"
|
||||||
|
static let datePublished = "datePublished"
|
||||||
|
static let dateModified = "dateModified"
|
||||||
|
static let authors = "authors"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CloudKitAuthor {
|
||||||
|
static let recordType = "Author"
|
||||||
|
struct Fields {
|
||||||
|
static let article = "article"
|
||||||
|
static let authorID = "authorID"
|
||||||
|
static let name = "name"
|
||||||
|
static let url = "url"
|
||||||
|
static let avatarURL = "avatarURL"
|
||||||
|
static let emailAddress = "emailAddress"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct CloudKitArticleStatus {
|
struct CloudKitArticleStatus {
|
||||||
static let recordType = "ArticleStatus"
|
static let recordType = "ArticleStatus"
|
||||||
struct Fields {
|
struct Fields {
|
||||||
|
@ -38,7 +70,17 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||||
self.database = container.privateCloudDatabase
|
self.database = container.privateCloudDatabase
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendArticleStatus(_ syncStatuses: [SyncStatus], completion: @escaping ((Result<Void, Error>) -> Void)) {
|
func sendArticleStatus(_ syncStatuses: [SyncStatus], starredArticles: Set<Article>, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
|
var records = makeStatusRecords(syncStatuses)
|
||||||
|
records.append(contentsOf: makeArticleRecords(starredArticles))
|
||||||
|
modify(recordsToSave: records, recordIDsToDelete: [], completion: completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension CloudKitArticlesZone {
|
||||||
|
|
||||||
|
func makeStatusRecords(_ syncStatuses: [SyncStatus]) -> [CKRecord] {
|
||||||
var records = [String: CKRecord]()
|
var records = [String: CKRecord]()
|
||||||
|
|
||||||
for status in syncStatuses {
|
for status in syncStatuses {
|
||||||
|
@ -60,7 +102,53 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(recordsToSave: Array(records.values), recordIDsToDelete: [], completion: completion)
|
return Array(records.values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeArticleRecords(_ articles: Set<Article>) -> [CKRecord] {
|
||||||
|
var records = [CKRecord]()
|
||||||
|
|
||||||
|
for article in articles {
|
||||||
|
|
||||||
|
let record = CKRecord(recordType: CloudKitArticle.recordType, recordID: generateRecordID())
|
||||||
|
|
||||||
|
let articleStatusRecordID = CKRecord.ID(recordName: article.articleID, zoneID: Self.zoneID)
|
||||||
|
record[CloudKitArticle.Fields.articleStatus] = CKRecord.Reference(recordID: articleStatusRecordID, action: .deleteSelf)
|
||||||
|
record[CloudKitArticle.Fields.webFeedID] = article.webFeedID
|
||||||
|
record[CloudKitArticle.Fields.uniqueID] = article.uniqueID
|
||||||
|
record[CloudKitArticle.Fields.title] = article.title
|
||||||
|
record[CloudKitArticle.Fields.contentHTML] = article.contentHTML
|
||||||
|
record[CloudKitArticle.Fields.contentText] = article.contentText
|
||||||
|
record[CloudKitArticle.Fields.url] = article.url
|
||||||
|
record[CloudKitArticle.Fields.externalURL] = article.externalURL
|
||||||
|
record[CloudKitArticle.Fields.summary] = article.summary
|
||||||
|
record[CloudKitArticle.Fields.imageURL] = article.imageURL
|
||||||
|
record[CloudKitArticle.Fields.datePublished] = article.datePublished
|
||||||
|
record[CloudKitArticle.Fields.dateModified] = article.dateModified
|
||||||
|
|
||||||
|
records.append(record)
|
||||||
|
|
||||||
|
if let authors = article.authors {
|
||||||
|
for author in authors {
|
||||||
|
records.append(makeAuthorRecord(record, author))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeAuthorRecord(_ articleRecord: CKRecord, _ author: Author) -> CKRecord {
|
||||||
|
let record = CKRecord(recordType: CloudKitAuthor.recordType, recordID: generateRecordID())
|
||||||
|
|
||||||
|
record[CloudKitAuthor.Fields.article] = CKRecord.Reference(record: articleRecord, action: .deleteSelf)
|
||||||
|
record[CloudKitAuthor.Fields.authorID] = author.authorID
|
||||||
|
record[CloudKitAuthor.Fields.name] = author.name
|
||||||
|
record[CloudKitAuthor.Fields.url] = author.url
|
||||||
|
record[CloudKitAuthor.Fields.avatarURL] = author.avatarURL
|
||||||
|
record[CloudKitAuthor.Fields.emailAddress] = author.emailAddress
|
||||||
|
|
||||||
|
return record
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue