Compress html and text content
This commit is contained in:
parent
947ceee7e7
commit
a51bcc2f0e
|
@ -25,6 +25,8 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||||
weak var database: CKDatabase?
|
weak var database: CKDatabase?
|
||||||
var delegate: CloudKitZoneDelegate? = nil
|
var delegate: CloudKitZoneDelegate? = nil
|
||||||
|
|
||||||
|
var compressionQueue = DispatchQueue(label: "Articles Zone Compression Queue")
|
||||||
|
|
||||||
struct CloudKitArticle {
|
struct CloudKitArticle {
|
||||||
static let recordType = "Article"
|
static let recordType = "Article"
|
||||||
struct Fields {
|
struct Fields {
|
||||||
|
@ -33,7 +35,9 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||||
static let uniqueID = "uniqueID"
|
static let uniqueID = "uniqueID"
|
||||||
static let title = "title"
|
static let title = "title"
|
||||||
static let contentHTML = "contentHTML"
|
static let contentHTML = "contentHTML"
|
||||||
|
static let contentHTMLData = "contentHTMLData"
|
||||||
static let contentText = "contentText"
|
static let contentText = "contentText"
|
||||||
|
static let contentTextData = "contentTextData"
|
||||||
static let url = "url"
|
static let url = "url"
|
||||||
static let externalURL = "externalURL"
|
static let externalURL = "externalURL"
|
||||||
static let summary = "summary"
|
static let summary = "summary"
|
||||||
|
@ -96,7 +100,11 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||||
records.append(makeArticleRecord(saveArticle))
|
records.append(makeArticleRecord(saveArticle))
|
||||||
}
|
}
|
||||||
|
|
||||||
save(records, completion: completion)
|
compressionQueue.async {
|
||||||
|
self.compressArticleRecords(records) { compressedRecords in
|
||||||
|
self.save(compressedRecords, completion: completion)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteArticles(_ webFeedExternalID: String, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
func deleteArticles(_ webFeedExternalID: String, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
|
@ -130,22 +138,29 @@ final class CloudKitArticlesZone: CloudKitZone {
|
||||||
deleteRecordIDs.append(CKRecord.ID(recordName: self.articleID(statusUpdate.articleID), zoneID: zoneID))
|
deleteRecordIDs.append(CKRecord.ID(recordName: self.articleID(statusUpdate.articleID), zoneID: zoneID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.modify(recordsToSave: modifyRecords, recordIDsToDelete: deleteRecordIDs) { result in
|
compressionQueue.async {
|
||||||
switch result {
|
self.compressArticleRecords(modifyRecords) { compressedModifyRecords in
|
||||||
case .success:
|
self.compressArticleRecords(newRecords) { compressedNewRecords in
|
||||||
self.saveIfNew(newRecords) { result in
|
self.modify(recordsToSave: compressedModifyRecords, recordIDsToDelete: deleteRecordIDs) { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
completion(.success(()))
|
self.saveIfNew(compressedNewRecords) { result in
|
||||||
case .failure(let error):
|
switch result {
|
||||||
completion(.failure(error))
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case .failure(let error):
|
||||||
|
self.handleModifyArticlesError(error, statusUpdates: statusUpdates, completion: completion)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .failure(let error):
|
|
||||||
self.handleModifyArticlesError(error, statusUpdates: statusUpdates, completion: completion)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -237,5 +252,37 @@ private extension CloudKitArticlesZone {
|
||||||
return record
|
return record
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compressArticleRecords(_ records: [CKRecord], completion: ([CKRecord]) -> Void ) {
|
||||||
|
var result = [CKRecord]()
|
||||||
|
|
||||||
|
for record in records {
|
||||||
|
|
||||||
|
if record.recordType == CloudKitArticle.recordType {
|
||||||
|
|
||||||
|
if let contentHTML = record[CloudKitArticle.Fields.contentHTML] as? String {
|
||||||
|
let data = Data(contentHTML.utf8) as NSData
|
||||||
|
if let compressedData = try? data.compressed(using: .lzfse) {
|
||||||
|
record[CloudKitArticle.Fields.contentHTMLData] = compressedData
|
||||||
|
record[CloudKitArticle.Fields.contentHTML] = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let contentText = record[CloudKitArticle.Fields.contentText] as? String {
|
||||||
|
let data = Data(contentText.utf8) as NSData
|
||||||
|
if let compressedData = try? data.compressed(using: .lzfse) {
|
||||||
|
record[CloudKitArticle.Fields.contentTextData] = compressedData
|
||||||
|
record[CloudKitArticle.Fields.contentText] = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
result.append(record)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(result)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate {
|
||||||
weak var account: Account?
|
weak var account: Account?
|
||||||
var database: SyncDatabase
|
var database: SyncDatabase
|
||||||
weak var articlesZone: CloudKitArticlesZone?
|
weak var articlesZone: CloudKitArticlesZone?
|
||||||
|
var compressionQueue = DispatchQueue(label: "Articles Zone Delegate Compression Queue")
|
||||||
|
|
||||||
init(account: Account, database: SyncDatabase, articlesZone: CloudKitArticlesZone) {
|
init(account: Account, database: SyncDatabase, articlesZone: CloudKitArticlesZone) {
|
||||||
self.account = account
|
self.account = account
|
||||||
|
@ -134,7 +135,7 @@ private extension CloudKitArticlesZoneDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
group.enter()
|
group.enter()
|
||||||
DispatchQueue.global(qos: .utility).async {
|
compressionQueue.async {
|
||||||
let parsedItems = records.compactMap { self.makeParsedItem($0) }
|
let parsedItems = records.compactMap { self.makeParsedItem($0) }
|
||||||
let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) }
|
let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) }
|
||||||
|
|
||||||
|
@ -199,6 +200,20 @@ private extension CloudKitArticlesZoneDelegate {
|
||||||
return nil
|
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,
|
let parsedItem = ParsedItem(syncServiceID: nil,
|
||||||
uniqueID: uniqueID,
|
uniqueID: uniqueID,
|
||||||
feedURL: webFeedURL,
|
feedURL: webFeedURL,
|
||||||
|
@ -206,8 +221,8 @@ private extension CloudKitArticlesZoneDelegate {
|
||||||
externalURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.externalURL] as? String,
|
externalURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.externalURL] as? String,
|
||||||
title: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.title] as? String,
|
title: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.title] as? String,
|
||||||
language: nil,
|
language: nil,
|
||||||
contentHTML: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentHTML] as? String,
|
contentHTML: contentHTML,
|
||||||
contentText: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentText] as? String,
|
contentText: contentText,
|
||||||
summary: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.summary] as? String,
|
summary: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.summary] as? String,
|
||||||
imageURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.imageURL] as? String,
|
imageURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.imageURL] as? String,
|
||||||
bannerImageURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.imageURL] as? String,
|
bannerImageURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.imageURL] as? String,
|
||||||
|
|
Loading…
Reference in New Issue