From 9c66f6160e295e8b433ee4850a70caa968cc2c84 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Wed, 28 Aug 2019 11:30:40 -0500 Subject: [PATCH] Clean activities when the associated data is deleted --- Shared/Activity/ActivityManager.swift | 70 ++++++++++++++++++- iOS/MasterFeed/MasterFeedViewController.swift | 6 ++ iOS/Settings/SettingsDetailAccountView.swift | 1 + .../UIKit/DetailAccountViewController.swift | 1 + 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/Shared/Activity/ActivityManager.swift b/Shared/Activity/ActivityManager.swift index 2c4bd27c6..977108ead 100644 --- a/Shared/Activity/ActivityManager.swift +++ b/Shared/Activity/ActivityManager.swift @@ -41,7 +41,7 @@ class ActivityManager { func selectingFolder(_ folder: Folder) { let localizedText = NSLocalizedString("See articles in “%@”", comment: "See articles in Folder") let title = NSString.localizedStringWithFormat(localizedText as NSString, folder.nameForDisplay) as String - selectingActivity = makeSelectingActivity(type: ActivityType.selectFolder, title: title, identifier: "folder.\(folder.nameForDisplay)") + selectingActivity = makeSelectingActivity(type: ActivityType.selectFolder, title: title, identifier: identifer(for: folder)) selectingActivity!.userInfo = [ ActivityID.accountID.rawValue: folder.account?.accountID ?? "", @@ -55,7 +55,7 @@ class ActivityManager { func selectingFeed(_ feed: Feed) { let localizedText = NSLocalizedString("See articles in “%@”", comment: "See articles in Feed") let title = NSString.localizedStringWithFormat(localizedText as NSString, feed.nameForDisplay) as String - selectingActivity = makeSelectingActivity(type: ActivityType.selectFeed, title: title, identifier: feed.url) + selectingActivity = makeSelectingActivity(type: ActivityType.selectFeed, title: title, identifier: identifer(for: feed)) selectingActivity!.userInfo = [ ActivityID.accountID.rawValue: feed.account?.accountID ?? "", @@ -63,6 +63,16 @@ class ActivityManager { ActivityID.feedID.rawValue: feed.feedID ] + let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String) + attributeSet.title = feed.nameForDisplay + attributeSet.keywords = makeKeywords(feed.nameForDisplay) + if let image = appDelegate.feedIconDownloader.icon(for: feed) { + attributeSet.thumbnailData = image.pngData() + } else if let image = appDelegate.faviconDownloader.faviconAsAvatar(for: feed) { + attributeSet.thumbnailData = image.pngData() + } + selectingActivity!.contentAttributeSet = attributeSet + selectingActivity!.becomeCurrent() } @@ -74,6 +84,37 @@ class ActivityManager { readingActivity?.becomeCurrent() } + func cleanUp(_ account: Account) { + var ids = [String]() + + if let folders = account.folders { + for folder in folders { + ids.append(identifer(for: folder)) + } + } + + for feed in account.flattenedFeeds() { + ids.append(contentsOf: identifers(for: feed)) + } + + NSUserActivity.deleteSavedUserActivities(withPersistentIdentifiers: ids) {} + } + + func cleanUp(_ folder: Folder) { + var ids = [String]() + ids.append(identifer(for: folder)) + + for feed in folder.flattenedFeeds() { + ids.append(contentsOf: identifers(for: feed)) + } + + NSUserActivity.deleteSavedUserActivities(withPersistentIdentifiers: ids) {} + } + + func cleanUp(_ feed: Feed) { + NSUserActivity.deleteSavedUserActivities(withPersistentIdentifiers: identifers(for: feed)) {} + } + } // MARK: Private @@ -110,13 +151,13 @@ private extension ActivityManager { activity.isEligibleForSearch = true activity.isEligibleForPrediction = false activity.isEligibleForHandoff = true + activity.persistentIdentifier = identifer(for: article) // CoreSpotlight let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeCompositeContent as String) attributeSet.title = article.title attributeSet.contentDescription = article.summary attributeSet.keywords = keywords - attributeSet.relatedUniqueIdentifier = article.url if let image = article.avatarImage() { attributeSet.thumbnailData = image.pngData() @@ -131,4 +172,27 @@ private extension ActivityManager { return value?.components(separatedBy: " ").filter { $0.count > 2 } ?? [] } + func identifer(for folder: Folder) -> String { + return "account_\(folder.account!.accountID)_folder_\(folder.nameForDisplay)" + } + + func identifer(for feed: Feed) -> String { + return "account_\(feed.account!.accountID)_feed_\(feed.feedID)" + } + + func identifer(for article: Article) -> String { + return "account_\(article.accountID)_feed_\(article.feedID)_article_\(article.articleID)" + } + + func identifers(for feed: Feed) -> [String] { + var ids = [String]() + ids.append(identifer(for: feed)) + + for article in feed.fetchArticles() { + ids.append(identifer(for: article)) + } + + return ids + } + } diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift index 14bd25023..9c2b0fdb1 100644 --- a/iOS/MasterFeed/MasterFeedViewController.swift +++ b/iOS/MasterFeed/MasterFeedViewController.swift @@ -859,6 +859,12 @@ private extension MasterFeedViewController { return } + if let folder = deleteNode.representedObject as? Folder { + ActivityManager.shared.cleanUp(folder) + } else if let feed = deleteNode.representedObject as? Feed { + ActivityManager.shared.cleanUp(feed) + } + var deleteIndexPaths = [indexPath] if coordinator.isExpanded(deleteNode) { for i in 0..