Add subscriptions to OPML imports.

This commit is contained in:
Maurice Parker 2020-04-04 17:35:09 -05:00
parent 5273187033
commit 0b87acec1e
3 changed files with 62 additions and 13 deletions

View File

@ -178,7 +178,55 @@ final class CloudKitAccountDelegate: AccountDelegate {
let normalizedItems = OPMLNormalizer.normalize(opmlItems)
accountZone.importOPML(rootExternalID: rootExternalID, items: normalizedItems, completion: completion)
var webFeedURLs = Set<String>()
for opmlItem in normalizedItems {
if let webFeedURL = opmlItem.feedSpecifier?.feedURL {
webFeedURLs.insert(webFeedURL)
} else {
if let childItems = opmlItem.children {
for childItem in childItems {
if let webFeedURL = childItem.feedSpecifier?.feedURL {
webFeedURLs.insert(webFeedURL)
}
}
}
}
}
refreshProgress.addToNumberOfTasksAndRemaining(webFeedURLs.count + 1)
var errorOccurred = false
// You have to single thread these or CloudKit gets overwhelmed and freaks out
func takeOneAndPassItOn(_ webFeedURLs: [String], completion: @escaping () -> Void) {
var remainingWebFeedURLS = webFeedURLs
if let webFeedURL = remainingWebFeedURLS.popLast() {
publicZone.createSubscription(webFeedURL) { result in
self.refreshProgress.completeTask()
if case .failure(let error) = result {
os_log(.error, log: self.log, "Error while subscribing to the feed: %@", error.localizedDescription)
errorOccurred = true
}
takeOneAndPassItOn(remainingWebFeedURLS, completion: completion)
}
} else {
completion()
}
}
takeOneAndPassItOn(Array(webFeedURLs)) {
if errorOccurred {
self.refreshProgress.completeTask()
completion(.failure(CloudKitZoneError.unknown))
} else {
self.accountZone.importOPML(rootExternalID: rootExternalID, items: normalizedItems) { _ in
self.refreshProgress.completeTask()
completion(.success(()))
}
}
}
}
func createWebFeed(for account: Account, url urlString: String, name: String?, container: Container, completion: @escaping (Result<WebFeed, Error>) -> Void) {
@ -221,10 +269,10 @@ final class CloudKitAccountDelegate: AccountDelegate {
feed.externalID = externalID
container.addWebFeed(feed)
self.publicZone.createSubscription(feed) { result in
self.publicZone.createSubscription(feed.url) { result in
self.refreshProgress.completeTask()
if case .failure(let error) = result {
os_log(.error, log: self.log, "An error occurred while creating the subscription: %@.", error.localizedDescription)
os_log(.error, log: self.log, "An error occurred while creating the subscription: %@", error.localizedDescription)
}
}
@ -442,7 +490,7 @@ final class CloudKitAccountDelegate: AccountDelegate {
}
func accountDidInitialize(_ account: Account) {
accountZone.delegate = CloudKitAcountZoneDelegate(account: account, refreshProgress: refreshProgress)
accountZone.delegate = CloudKitAcountZoneDelegate(account: account, publicZone: publicZone, refreshProgress: refreshProgress)
articlesZone.delegate = CloudKitArticlesZoneDelegate(account: account, database: database, articlesZone: articlesZone)
// Check to see if this is a new account and initialize anything we need

View File

@ -60,8 +60,9 @@ final class CloudKitPublicZone: CloudKitZone {
}
/// Create a CloudKit subscription for the webfeed and any other supporting records that we need
func createSubscription(_ webFeed: WebFeed, completion: @escaping (Result<Void, Error>) -> Void) {
func createSubscription(_ webFeedURL: String, completion: @escaping (Result<Void, Error>) -> Void) {
let webFeedURLMD5String = webFeedURL.md5String
func createSubscription(_ webFeedRecordRef: CKRecord.Reference) {
let predicate = NSPredicate(format: "webFeed = %@", webFeedRecordRef)
let subscription = CKQuerySubscription(recordType: CloudKitWebFeed.recordType, predicate: predicate, options: [.firesOnRecordUpdate])
@ -88,7 +89,7 @@ final class CloudKitPublicZone: CloudKitZone {
}
}
fetch(externalID: webFeed.url.md5String) { result in
fetch(externalID: webFeedURLMD5String) { result in
switch result {
case .success(let record):
@ -97,10 +98,10 @@ final class CloudKitPublicZone: CloudKitZone {
case .failure:
let webFeedRecordID = CKRecord.ID(recordName: webFeed.url.md5String, zoneID: Self.zoneID)
let webFeedRecordID = CKRecord.ID(recordName: webFeedURLMD5String, zoneID: Self.zoneID)
let webFeedRecordRef = CKRecord.Reference(recordID: webFeedRecordID, action: .none)
let webFeedRecord = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: webFeedRecordID)
webFeedRecord[CloudKitWebFeed.Fields.url] = webFeed.url
webFeedRecord[CloudKitWebFeed.Fields.url] = webFeedURL
webFeedRecord[CloudKitWebFeed.Fields.httpLastModified] = ""
webFeedRecord[CloudKitWebFeed.Fields.httpEtag] = ""

View File

@ -72,7 +72,7 @@ extension CloudKitZone {
save(subscription) { result in
if case .failure(let error) = result {
os_log(.error, log: self.log, "%@ zone subscribe to changes error: %@.", Self.zoneID.zoneName, error.localizedDescription)
os_log(.error, log: self.log, "%@ zone subscribe to changes error: %@", Self.zoneID.zoneName, error.localizedDescription)
}
}
}
@ -86,7 +86,7 @@ extension CloudKitZone {
fetchChangesInZone() { result in
if case .failure(let error) = result {
os_log(.error, log: self.log, "%@ zone remote notification fetch error: %@.", Self.zoneID.zoneName, error.localizedDescription)
os_log(.error, log: self.log, "%@ zone remote notification fetch error: %@", Self.zoneID.zoneName, error.localizedDescription)
}
completion()
}
@ -319,7 +319,7 @@ extension CloudKitZone {
group.enter()
self.modify(recordsToSave: chunk, recordIDsToDelete: recordIDsToDelete) { result in
if case .failure(let error) = result {
os_log(.error, log: self.log, "%@ zone modify records error: %@.", Self.zoneID.zoneName, error.localizedDescription)
os_log(.error, log: self.log, "%@ zone modify records error: %@", Self.zoneID.zoneName, error.localizedDescription)
errorOccurred = true
}
group.leave()
@ -396,7 +396,7 @@ extension CloudKitZone {
self.fetchChangesInZone(completion: completion)
}
default:
os_log(.error, log: self.log, "%@ zone fetch changes error: %@.", zoneID.zoneName, error?.localizedDescription ?? "Unknown")
os_log(.error, log: self.log, "%@ zone fetch changes error: %@", zoneID.zoneName, error?.localizedDescription ?? "Unknown")
}
}