Sync the WebFeed username so that Feed Provider created feeds stay locked to their accounts.

This commit is contained in:
Maurice Parker 2020-04-22 17:42:20 -05:00
parent 3eecae95e1
commit 14156e3774
3 changed files with 23 additions and 16 deletions

View File

@ -292,7 +292,7 @@ final class CloudKitAccountDelegate: AccountDelegate {
func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
refreshProgress.addToNumberOfTasksAndRemaining(1)
accountZone.createWebFeed(url: feed.url, editedName: feed.editedName, container: container) { result in
accountZone.createWebFeed(url: feed.url, editedName: feed.editedName, username: feed.username, container: container) { result in
self.refreshProgress.completeTask()
switch result {
case .success(let externalID):
@ -615,7 +615,7 @@ private extension CloudKitAccountDelegate {
return
}
self.accountZone.createWebFeed(url: newURLString, editedName: editedName, container: container) { result in
self.accountZone.createWebFeed(url: newURLString, editedName: editedName, username: urlComponents.user, container: container) { result in
self.refreshProgress.completeTask()
switch result {
@ -674,7 +674,7 @@ private extension CloudKitAccountDelegate {
return
}
self.accountZone.createWebFeed(url: bestFeedSpecifier.urlString, editedName: editedName, container: container) { result in
self.accountZone.createWebFeed(url: bestFeedSpecifier.urlString, editedName: editedName, username: nil, container: container) { result in
self.refreshProgress.completeTask()
switch result {

View File

@ -29,6 +29,7 @@ final class CloudKitAccountZone: CloudKitZone {
struct Fields {
static let url = "url"
static let editedName = "editedName"
static let username = "username"
static let containerExternalIDs = "containerExternalIDs"
}
}
@ -81,13 +82,16 @@ final class CloudKitAccountZone: CloudKitZone {
}
/// 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, editedName: String?, username: String?, container: Container, completion: @escaping (Result<String, Error>) -> Void) {
let recordID = CKRecord.ID(recordName: url.md5String, zoneID: Self.zoneID)
let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID)
record[CloudKitWebFeed.Fields.url] = url
if let editedName = editedName {
record[CloudKitWebFeed.Fields.editedName] = editedName
}
if let username = username {
record[CloudKitWebFeed.Fields.username] = username
}
guard let containerExternalID = container.externalID else {
completion(.failure(CloudKitZoneError.invalidParameter))

View File

@ -13,7 +13,7 @@ import CloudKit
class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
private typealias UnclaimedWebFeed = (url: URL, editedName: String?, webFeedExternalID: String)
private typealias UnclaimedWebFeed = (url: URL, editedName: String?, username: String?, webFeedExternalID: String)
private var unclaimedWebFeeds = [String: [UnclaimedWebFeed]]()
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit")
@ -72,10 +72,11 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
}
let editedName = record[CloudKitAccountZone.CloudKitWebFeed.Fields.editedName] as? String
let username = record[CloudKitAccountZone.CloudKitWebFeed.Fields.username] as? String
if let webFeed = account.existingWebFeed(withExternalID: record.externalID) {
updateWebFeed(webFeed, editedName: editedName, containerExternalIDs: containerExternalIDs)
updateWebFeed(webFeed, editedName: editedName, username: username, containerExternalIDs: containerExternalIDs)
completion()
} else {
@ -84,11 +85,11 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
for containerExternalID in containerExternalIDs {
group.enter()
if let container = account.existingContainer(withExternalID: containerExternalID) {
createWebFeedIfNecessary(url: url, editedName: editedName, webFeedExternalID: record.externalID, container: container) { webFeed in
createWebFeedIfNecessary(url: url, editedName: editedName, username: username, webFeedExternalID: record.externalID, container: container) { webFeed in
group.leave()
}
} else {
addUnclaimedWebFeed(url: url, editedName: editedName, webFeedExternalID: record.externalID, containerExternalID: containerExternalID)
addUnclaimedWebFeed(url: url, editedName: editedName, username: username, webFeedExternalID: record.externalID, containerExternalID: containerExternalID)
group.leave()
}
}
@ -129,7 +130,7 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
for unclaimedWebFeed in unclaimedWebFeeds {
group.enter()
createWebFeedIfNecessary(url: unclaimedWebFeed.url, editedName: unclaimedWebFeed.editedName, webFeedExternalID: unclaimedWebFeed.webFeedExternalID, container: folder) { webFeed in
createWebFeedIfNecessary(url: unclaimedWebFeed.url, editedName: unclaimedWebFeed.editedName, username: unclaimedWebFeed.username, webFeedExternalID: unclaimedWebFeed.webFeedExternalID, container: folder) { webFeed in
group.leave()
}
}
@ -156,9 +157,10 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
private extension CloudKitAcountZoneDelegate {
func updateWebFeed(_ webFeed: WebFeed, editedName: String?, containerExternalIDs: [String]) {
func updateWebFeed(_ webFeed: WebFeed, editedName: String?, username: String?, containerExternalIDs: [String]) {
guard let account = account else { return }
webFeed.editedName = editedName
webFeed.username = username
let existingContainers = account.existingContainers(withWebFeed: webFeed)
let existingContainerExternalIds = existingContainers.compactMap { $0.externalID }
@ -179,7 +181,7 @@ private extension CloudKitAcountZoneDelegate {
}
}
func createWebFeedIfNecessary(url: URL, editedName: String?, webFeedExternalID: String, container: Container, completion: @escaping (WebFeed) -> Void) {
func createWebFeedIfNecessary(url: URL, editedName: String?, username: String?, webFeedExternalID: String, container: Container, completion: @escaping (WebFeed) -> Void) {
guard let account = account, let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return }
if let webFeed = account.existingWebFeed(withExternalID: webFeedExternalID) {
@ -189,9 +191,10 @@ private extension CloudKitAcountZoneDelegate {
let webFeed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil)
webFeed.editedName = editedName
webFeed.username = username
webFeed.externalID = webFeedExternalID
if let feedProvider = FeedProviderManager.shared.best(for: urlComponents, with: nil) {
if let feedProvider = FeedProviderManager.shared.best(for: urlComponents, with: username) {
refreshProgress?.addToNumberOfTasksAndRemaining(2)
feedProvider.assignName(urlComponents) { result in
@ -239,13 +242,13 @@ private extension CloudKitAcountZoneDelegate {
}
func addUnclaimedWebFeed(url: URL, editedName: String?, webFeedExternalID: String, containerExternalID: String) {
func addUnclaimedWebFeed(url: URL, editedName: String?, username: String?, webFeedExternalID: String, containerExternalID: String) {
if var unclaimedWebFeeds = self.unclaimedWebFeeds[containerExternalID] {
unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, editedName: editedName, webFeedExternalID: webFeedExternalID))
unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, editedName: editedName, username: username, webFeedExternalID: webFeedExternalID))
self.unclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds
} else {
var unclaimedWebFeeds = [UnclaimedWebFeed]()
unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, editedName: editedName, webFeedExternalID: webFeedExternalID))
unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, editedName: editedName, username: username, webFeedExternalID: webFeedExternalID))
self.unclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds
}
}