Rebuild the import OPML and initial device add processes.
This commit is contained in:
parent
09addec369
commit
48dbc4958f
@ -97,11 +97,6 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
guard refreshProgress.isComplete else {
|
|
||||||
completion(.success(()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
os_log(.debug, log: log, "Sending article statuses...")
|
os_log(.debug, log: log, "Sending article statuses...")
|
||||||
|
|
||||||
database.selectForProcessing { result in
|
database.selectForProcessing { result in
|
||||||
@ -154,11 +149,6 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
|||||||
|
|
||||||
|
|
||||||
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
guard refreshProgress.isComplete else {
|
|
||||||
completion(.success(()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
os_log(.debug, log: log, "Refreshing article statuses...")
|
os_log(.debug, log: log, "Refreshing article statuses...")
|
||||||
|
|
||||||
articlesZone.refreshArticles() { result in
|
articlesZone.refreshArticles() { result in
|
||||||
@ -214,7 +204,7 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
|||||||
let normalizedItems = OPMLNormalizer.normalize(opmlItems)
|
let normalizedItems = OPMLNormalizer.normalize(opmlItems)
|
||||||
|
|
||||||
self.accountZone.importOPML(rootExternalID: rootExternalID, items: normalizedItems) { _ in
|
self.accountZone.importOPML(rootExternalID: rootExternalID, items: normalizedItems) { _ in
|
||||||
self.initialRefreshAll(for: account, completion: completion)
|
self.standardRefreshAll(for: account, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -309,7 +299,7 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
|||||||
|
|
||||||
func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||||
accountZone.createWebFeed(url: feed.url, editedName: feed.editedName, container: container) { result in
|
accountZone.createWebFeed(url: feed.url, name: feed.name, editedName: feed.editedName, container: container) { result in
|
||||||
self.refreshProgress.completeTask()
|
self.refreshProgress.completeTask()
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let externalID):
|
case .success(let externalID):
|
||||||
@ -494,32 +484,22 @@ private extension CloudKitAccountDelegate {
|
|||||||
completion(.failure(error))
|
completion(.failure(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshProgress.addToNumberOfTasksAndRemaining(3)
|
refreshProgress.addToNumberOfTasksAndRemaining(2)
|
||||||
refreshArticleStatus(for: account) { result in
|
accountZone.fetchChangesInZone() { result in
|
||||||
switch result {
|
|
||||||
case .success:
|
|
||||||
|
|
||||||
self.refreshProgress.completeTask()
|
self.refreshProgress.completeTask()
|
||||||
self.accountZone.fetchChangesInZone() { result in
|
|
||||||
switch result {
|
|
||||||
case .success:
|
|
||||||
|
|
||||||
self.refreshProgress.completeTask()
|
|
||||||
self.sendArticleStatus(for: account) { result in
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
self.refreshProgress.clear()
|
self.refreshArticleStatus(for: account) { result in
|
||||||
|
self.refreshProgress.completeTask()
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
account.metadata.lastArticleFetchEndTime = Date()
|
account.metadata.lastArticleFetchEndTime = Date()
|
||||||
completion(.success(()))
|
completion(.success(()))
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
fail(error)
|
fail(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case .failure(let error):
|
|
||||||
fail(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
fail(error)
|
fail(error)
|
||||||
}
|
}
|
||||||
@ -667,7 +647,7 @@ private extension CloudKitAccountDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.accountZone.createWebFeed(url: urlString, editedName: editedName, container: container) { result in
|
self.accountZone.createWebFeed(url: urlString, name: name, editedName: editedName, container: container) { result in
|
||||||
|
|
||||||
self.refreshProgress.completeTask()
|
self.refreshProgress.completeTask()
|
||||||
switch result {
|
switch result {
|
||||||
@ -751,15 +731,8 @@ private extension CloudKitAccountDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.accountZone.createWebFeed(url: bestFeedSpecifier.urlString, editedName: editedName, container: container) { result in
|
|
||||||
|
|
||||||
self.refreshProgress.completeTask()
|
|
||||||
switch result {
|
|
||||||
case .success(let externalID):
|
|
||||||
|
|
||||||
let feed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil)
|
let feed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil)
|
||||||
feed.editedName = editedName
|
feed.editedName = editedName
|
||||||
feed.externalID = externalID
|
|
||||||
container.addWebFeed(feed)
|
container.addWebFeed(feed)
|
||||||
|
|
||||||
InitialFeedDownloader.download(url) { parsedFeed in
|
InitialFeedDownloader.download(url) { parsedFeed in
|
||||||
@ -769,8 +742,16 @@ private extension CloudKitAccountDelegate {
|
|||||||
account.update(feed, with: parsedFeed) { result in
|
account.update(feed, with: parsedFeed) { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let articleChanges):
|
case .success(let articleChanges):
|
||||||
|
|
||||||
BatchUpdate.shared.end()
|
BatchUpdate.shared.end()
|
||||||
|
|
||||||
|
self.accountZone.createWebFeed(url: bestFeedSpecifier.urlString, name: parsedFeed.title, editedName: editedName, container: container) { result in
|
||||||
|
|
||||||
|
self.refreshProgress.completeTask()
|
||||||
|
switch result {
|
||||||
|
case .success(let externalID):
|
||||||
|
|
||||||
|
feed.externalID = externalID
|
||||||
|
|
||||||
var newAndUpdatedArticles = articleChanges.newArticles ?? Set<Article>()
|
var newAndUpdatedArticles = articleChanges.newArticles ?? Set<Article>()
|
||||||
newAndUpdatedArticles.formUnion(articleChanges.updatedArticles ?? Set<Article>())
|
newAndUpdatedArticles.formUnion(articleChanges.updatedArticles ?? Set<Article>())
|
||||||
let deletedArticles = articleChanges.deletedArticles ?? Set<Article>()
|
let deletedArticles = articleChanges.deletedArticles ?? Set<Article>()
|
||||||
@ -786,6 +767,14 @@ private extension CloudKitAccountDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
BatchUpdate.shared.end()
|
||||||
|
self.refreshProgress.clear()
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
self.refreshProgress.clear()
|
self.refreshProgress.clear()
|
||||||
completion(.failure(error))
|
completion(.failure(error))
|
||||||
@ -799,13 +788,6 @@ private extension CloudKitAccountDelegate {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case .failure(let error):
|
|
||||||
BatchUpdate.shared.end()
|
|
||||||
self.refreshProgress.clear()
|
|
||||||
completion(.failure(error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case .failure:
|
case .failure:
|
||||||
BatchUpdate.shared.end()
|
BatchUpdate.shared.end()
|
||||||
self.refreshProgress.clear()
|
self.refreshProgress.clear()
|
||||||
|
@ -28,6 +28,7 @@ final class CloudKitAccountZone: CloudKitZone {
|
|||||||
static let recordType = "AccountWebFeed"
|
static let recordType = "AccountWebFeed"
|
||||||
struct Fields {
|
struct Fields {
|
||||||
static let url = "url"
|
static let url = "url"
|
||||||
|
static let name = "name"
|
||||||
static let editedName = "editedName"
|
static let editedName = "editedName"
|
||||||
static let containerExternalIDs = "containerExternalIDs"
|
static let containerExternalIDs = "containerExternalIDs"
|
||||||
}
|
}
|
||||||
@ -81,10 +82,11 @@ final class CloudKitAccountZone: CloudKitZone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Persist a web feed record to iCloud and return the external key
|
/// Persist a web feed record to iCloud and return the external key
|
||||||
func createWebFeed(url: String, editedName: String?, container: Container, completion: @escaping (Result<String, Error>) -> Void) {
|
func createWebFeed(url: String, name: String?, editedName: String?, container: Container, completion: @escaping (Result<String, Error>) -> Void) {
|
||||||
let recordID = CKRecord.ID(recordName: url.md5String, zoneID: Self.zoneID)
|
let recordID = CKRecord.ID(recordName: url.md5String, zoneID: Self.zoneID)
|
||||||
let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID)
|
let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID)
|
||||||
record[CloudKitWebFeed.Fields.url] = url
|
record[CloudKitWebFeed.Fields.url] = url
|
||||||
|
record[CloudKitWebFeed.Fields.name] = name
|
||||||
if let editedName = editedName {
|
if let editedName = editedName {
|
||||||
record[CloudKitWebFeed.Fields.editedName] = editedName
|
record[CloudKitWebFeed.Fields.editedName] = editedName
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import Articles
|
|||||||
|
|
||||||
class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
|
class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
|
||||||
|
|
||||||
private typealias UnclaimedWebFeed = (url: URL, editedName: String?, webFeedExternalID: String)
|
private typealias UnclaimedWebFeed = (url: URL, name: String?, editedName: String?, webFeedExternalID: String)
|
||||||
private var unclaimedWebFeeds = [String: [UnclaimedWebFeed]]()
|
private var unclaimedWebFeeds = [String: [UnclaimedWebFeed]]()
|
||||||
|
|
||||||
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
|
||||||
@ -42,65 +42,41 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let group = DispatchGroup()
|
|
||||||
|
|
||||||
for changedRecord in changed {
|
for changedRecord in changed {
|
||||||
switch changedRecord.recordType {
|
switch changedRecord.recordType {
|
||||||
case CloudKitAccountZone.CloudKitWebFeed.recordType:
|
case CloudKitAccountZone.CloudKitWebFeed.recordType:
|
||||||
group.enter()
|
addOrUpdateWebFeed(changedRecord)
|
||||||
addOrUpdateWebFeed(changedRecord) {
|
|
||||||
group.leave()
|
|
||||||
}
|
|
||||||
case CloudKitAccountZone.CloudKitContainer.recordType:
|
case CloudKitAccountZone.CloudKitContainer.recordType:
|
||||||
group.enter()
|
addOrUpdateContainer(changedRecord)
|
||||||
addOrUpdateContainer(changedRecord) {
|
|
||||||
group.leave()
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
assertionFailure("Unknown record type: \(changedRecord.recordType)")
|
assertionFailure("Unknown record type: \(changedRecord.recordType)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group.notify(queue: DispatchQueue.main) {
|
|
||||||
completion(.success(()))
|
completion(.success(()))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func addOrUpdateWebFeed(_ record: CKRecord, completion: @escaping () -> Void) {
|
func addOrUpdateWebFeed(_ record: CKRecord) {
|
||||||
guard let account = account,
|
guard let account = account,
|
||||||
let urlString = record[CloudKitAccountZone.CloudKitWebFeed.Fields.url] as? String,
|
let urlString = record[CloudKitAccountZone.CloudKitWebFeed.Fields.url] as? String,
|
||||||
let containerExternalIDs = record[CloudKitAccountZone.CloudKitWebFeed.Fields.containerExternalIDs] as? [String],
|
let containerExternalIDs = record[CloudKitAccountZone.CloudKitWebFeed.Fields.containerExternalIDs] as? [String],
|
||||||
let url = URL(string: urlString) else {
|
let url = URL(string: urlString) else {
|
||||||
completion()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let name = record[CloudKitAccountZone.CloudKitWebFeed.Fields.name] as? String
|
||||||
let editedName = record[CloudKitAccountZone.CloudKitWebFeed.Fields.editedName] as? String
|
let editedName = record[CloudKitAccountZone.CloudKitWebFeed.Fields.editedName] as? String
|
||||||
|
|
||||||
if let webFeed = account.existingWebFeed(withExternalID: record.externalID) {
|
if let webFeed = account.existingWebFeed(withExternalID: record.externalID) {
|
||||||
|
updateWebFeed(webFeed, name: name, editedName: editedName, containerExternalIDs: containerExternalIDs)
|
||||||
updateWebFeed(webFeed, editedName: editedName, containerExternalIDs: containerExternalIDs)
|
|
||||||
completion()
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
let group = DispatchGroup()
|
|
||||||
for containerExternalID in containerExternalIDs {
|
for containerExternalID in containerExternalIDs {
|
||||||
group.enter()
|
|
||||||
if let container = account.existingContainer(withExternalID: containerExternalID) {
|
if let container = account.existingContainer(withExternalID: containerExternalID) {
|
||||||
createWebFeedIfNecessary(url: url, editedName: editedName, webFeedExternalID: record.externalID, container: container) { webFeed in
|
createWebFeedIfNecessary(url: url, name: name, editedName: editedName, webFeedExternalID: record.externalID, container: container)
|
||||||
group.leave()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
addUnclaimedWebFeed(url: url, editedName: editedName, webFeedExternalID: record.externalID, containerExternalID: containerExternalID)
|
addUnclaimedWebFeed(url: url, name: name, editedName: editedName, webFeedExternalID: record.externalID, containerExternalID: containerExternalID)
|
||||||
group.leave()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group.notify(queue: DispatchQueue.main) {
|
|
||||||
completion()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,12 +86,11 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addOrUpdateContainer(_ record: CKRecord, completion: @escaping () -> Void) {
|
func addOrUpdateContainer(_ record: CKRecord) {
|
||||||
guard let account = account,
|
guard let account = account,
|
||||||
let name = record[CloudKitAccountZone.CloudKitContainer.Fields.name] as? String,
|
let name = record[CloudKitAccountZone.CloudKitContainer.Fields.name] as? String,
|
||||||
let isAccount = record[CloudKitAccountZone.CloudKitContainer.Fields.isAccount] as? String,
|
let isAccount = record[CloudKitAccountZone.CloudKitContainer.Fields.isAccount] as? String,
|
||||||
isAccount != "1" else {
|
isAccount != "1" else {
|
||||||
completion()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,26 +103,17 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let folder = folder, let containerExternalID = folder.externalID, let unclaimedWebFeeds = unclaimedWebFeeds[containerExternalID] {
|
if let folder = folder, let containerExternalID = folder.externalID, let unclaimedWebFeeds = unclaimedWebFeeds[containerExternalID] {
|
||||||
|
|
||||||
let group = DispatchGroup()
|
|
||||||
|
|
||||||
for unclaimedWebFeed in unclaimedWebFeeds {
|
for unclaimedWebFeed in unclaimedWebFeeds {
|
||||||
group.enter()
|
createWebFeedIfNecessary(url: unclaimedWebFeed.url,
|
||||||
createWebFeedIfNecessary(url: unclaimedWebFeed.url, editedName: unclaimedWebFeed.editedName, webFeedExternalID: unclaimedWebFeed.webFeedExternalID, container: folder) { webFeed in
|
name: unclaimedWebFeed.name,
|
||||||
group.leave()
|
editedName: unclaimedWebFeed.editedName,
|
||||||
}
|
webFeedExternalID: unclaimedWebFeed.webFeedExternalID,
|
||||||
|
container: folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
group.notify(queue: DispatchQueue.main) {
|
|
||||||
self.unclaimedWebFeeds.removeValue(forKey: containerExternalID)
|
self.unclaimedWebFeeds.removeValue(forKey: containerExternalID)
|
||||||
completion()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
completion()
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeContainer(_ externalID: String) {
|
func removeContainer(_ externalID: String) {
|
||||||
@ -160,8 +126,10 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
|
|||||||
|
|
||||||
private extension CloudKitAcountZoneDelegate {
|
private extension CloudKitAcountZoneDelegate {
|
||||||
|
|
||||||
func updateWebFeed(_ webFeed: WebFeed, editedName: String?, containerExternalIDs: [String]) {
|
func updateWebFeed(_ webFeed: WebFeed, name: String?, editedName: String?, containerExternalIDs: [String]) {
|
||||||
guard let account = account else { return }
|
guard let account = account else { return }
|
||||||
|
|
||||||
|
webFeed.name = name
|
||||||
webFeed.editedName = editedName
|
webFeed.editedName = editedName
|
||||||
|
|
||||||
let existingContainers = account.existingContainers(withWebFeed: webFeed)
|
let existingContainers = account.existingContainers(withWebFeed: webFeed)
|
||||||
@ -183,121 +151,26 @@ private extension CloudKitAcountZoneDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createWebFeedIfNecessary(url: URL, editedName: String?, webFeedExternalID: String, container: Container, completion: @escaping (WebFeed) -> Void) {
|
func createWebFeedIfNecessary(url: URL, name: String?, editedName: String?, webFeedExternalID: String, container: Container) {
|
||||||
guard let account = account, let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return }
|
guard let account = account else { return }
|
||||||
|
|
||||||
if let webFeed = account.existingWebFeed(withExternalID: webFeedExternalID) {
|
if account.existingWebFeed(withExternalID: webFeedExternalID) != nil {
|
||||||
completion(webFeed)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let webFeed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil)
|
let webFeed = account.createWebFeed(with: name, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil)
|
||||||
webFeed.editedName = editedName
|
webFeed.editedName = editedName
|
||||||
webFeed.externalID = webFeedExternalID
|
webFeed.externalID = webFeedExternalID
|
||||||
|
|
||||||
if let feedProvider = FeedProviderManager.shared.best(for: urlComponents) {
|
|
||||||
|
|
||||||
refreshProgress?.addToNumberOfTasksAndRemaining(5)
|
|
||||||
feedProvider.assignName(urlComponents) { result in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
switch result {
|
|
||||||
case .success(let name):
|
|
||||||
|
|
||||||
webFeed.name = name
|
|
||||||
container.addWebFeed(webFeed)
|
container.addWebFeed(webFeed)
|
||||||
|
|
||||||
feedProvider.refresh(webFeed) { result in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
switch result {
|
|
||||||
case .success(let parsedItems):
|
|
||||||
account.update(url.absoluteString, with: parsedItems) { result in
|
|
||||||
switch result {
|
|
||||||
case .success(let articleChanges):
|
|
||||||
|
|
||||||
var newAndUpdatedArticles = articleChanges.newArticles ?? Set<Article>()
|
|
||||||
newAndUpdatedArticles.formUnion(articleChanges.updatedArticles ?? Set<Article>())
|
|
||||||
let deletedArticles = articleChanges.deletedArticles ?? Set<Article>()
|
|
||||||
newAndUpdatedArticles = newAndUpdatedArticles.subtracting(deletedArticles)
|
|
||||||
|
|
||||||
self.articlesZone?.deleteArticles(deletedArticles) { _ in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
self.articlesZone?.saveNewArticles(newAndUpdatedArticles) { _ in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
self.articlesZone?.fetchChangesInZone() { _ in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
completion(webFeed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case .failure:
|
func addUnclaimedWebFeed(url: URL, name: String?, editedName: String?, webFeedExternalID: String, containerExternalID: String) {
|
||||||
completion(webFeed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case .failure:
|
|
||||||
completion(webFeed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case .failure:
|
|
||||||
completion(webFeed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
refreshProgress?.addToNumberOfTasksAndRemaining(4)
|
|
||||||
|
|
||||||
BatchUpdate.shared.start()
|
|
||||||
InitialFeedDownloader.download(url) { parsedFeed in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
|
|
||||||
if let parsedFeed = parsedFeed {
|
|
||||||
container.addWebFeed(webFeed)
|
|
||||||
|
|
||||||
account.update(webFeed, with: parsedFeed, { result in
|
|
||||||
BatchUpdate.shared.end()
|
|
||||||
switch result {
|
|
||||||
case .success(let articleChanges):
|
|
||||||
|
|
||||||
var newAndUpdatedArticles = articleChanges.newArticles ?? Set<Article>()
|
|
||||||
newAndUpdatedArticles.formUnion(articleChanges.updatedArticles ?? Set<Article>())
|
|
||||||
let deletedArticles = articleChanges.deletedArticles ?? Set<Article>()
|
|
||||||
newAndUpdatedArticles = newAndUpdatedArticles.subtracting(deletedArticles)
|
|
||||||
|
|
||||||
self.articlesZone?.deleteArticles(deletedArticles) { _ in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
self.articlesZone?.saveNewArticles(newAndUpdatedArticles) { _ in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
self.articlesZone?.fetchChangesInZone() { _ in
|
|
||||||
self.refreshProgress?.completeTask()
|
|
||||||
completion(webFeed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case .failure:
|
|
||||||
completion(webFeed)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
} else {
|
|
||||||
BatchUpdate.shared.end()
|
|
||||||
completion(webFeed)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func addUnclaimedWebFeed(url: URL, editedName: String?, webFeedExternalID: String, containerExternalID: String) {
|
|
||||||
if var unclaimedWebFeeds = self.unclaimedWebFeeds[containerExternalID] {
|
if var unclaimedWebFeeds = self.unclaimedWebFeeds[containerExternalID] {
|
||||||
unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, editedName: editedName, webFeedExternalID: webFeedExternalID))
|
unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, name: name, editedName: editedName, webFeedExternalID: webFeedExternalID))
|
||||||
self.unclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds
|
self.unclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds
|
||||||
} else {
|
} else {
|
||||||
var unclaimedWebFeeds = [UnclaimedWebFeed]()
|
var unclaimedWebFeeds = [UnclaimedWebFeed]()
|
||||||
unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, editedName: editedName, webFeedExternalID: webFeedExternalID))
|
unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, name: name, editedName: editedName, webFeedExternalID: webFeedExternalID))
|
||||||
self.unclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds
|
self.unclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user