From 9d8d212f3c6ac25d4bb39619b8e9b9e63abd6d84 Mon Sep 17 00:00:00 2001 From: Dave Marquard Date: Mon, 19 Jul 2021 12:28:13 -0700 Subject: [PATCH 1/5] - correct subscription API calls - move subscription rather than deleting and re-adding it - include authors --- .../ReaderAPI/ReaderAPIAccountDelegate.swift | 64 +++--- .../Account/ReaderAPI/ReaderAPICaller.swift | 204 ++++++------------ .../Account/ReaderAPI/ReaderAPIEntry.swift | 2 + 3 files changed, 90 insertions(+), 180 deletions(-) diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 16d333340..98ca926c7 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -473,14 +473,23 @@ final class ReaderAPIAccountDelegate: AccountDelegate { if from is Account { addWebFeed(for: account, with: feed, to: to, completion: completion) } else { - deleteTagging(for: account, with: feed, from: from) { result in - switch result { - case .success: - self.addWebFeed(for: account, with: feed, to: to, completion: completion) - case .failure(let error): - completion(.failure(error)) - } - } + guard let subscriptionId = feed.externalID, let fromTag = (from as? Folder)?.name, let toTag = (to as? Folder)?.name else { + completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) + return + } + + refreshProgress.addToNumberOfTasksAndRemaining(1) + caller.moveSubscription(subscriptionID: subscriptionId, fromTag: fromTag, toTag: toTag) { result in + self.refreshProgress.completeTask() + switch result { + case .success: + from.removeWebFeed(feed) + to.addWebFeed(feed) + completion(.success(())) + case .failure(let error): + completion(.failure(error)) + } + } } } @@ -1008,8 +1017,13 @@ private extension ReaderAPIAccountDelegate { guard let streamID = entry.origin.streamId else { return nil } - // let authors = Set([ParsedAuthor(name: entry.authorName, url: entry.jsonFeed?.jsonFeedAuthor?.url, avatarURL: entry.jsonFeed?.jsonFeedAuthor?.avatarURL, emailAddress: nil)]) - // let feed = account.idToFeedDictionary[entry.origin.streamId!]! // TODO clean this up + + var authors: Set? { + guard let name = entry.author else { + return nil + } + return Set([ParsedAuthor(name: name, url: nil, avatarURL: nil, emailAddress: nil)]) + } return ParsedItem(syncServiceID: entry.uniqueID(variant: variant), uniqueID: entry.uniqueID(variant: variant), @@ -1025,7 +1039,7 @@ private extension ReaderAPIAccountDelegate { bannerImageURL: nil, datePublished: entry.parseDatePublished(), dateModified: nil, - authors: nil, + authors: authors, tags: nil, attachments: nil) } @@ -1132,32 +1146,4 @@ private extension ReaderAPIAccountDelegate { } - func deleteTagging(for account: Account, with feed: WebFeed, from container: Container?, completion: @escaping (Result) -> Void) { - - if let folder = container as? Folder, let feedName = feed.externalID { - caller.deleteTagging(subscriptionID: feedName, tagName: folder.name ?? "") { result in - switch result { - case .success: - DispatchQueue.main.async { - self.clearFolderRelationship(for: feed, folderExternalID: folder.externalID) - folder.removeWebFeed(feed) - account.addFeedIfNotInAnyFolder(feed) - completion(.success(())) - } - case .failure(let error): - DispatchQueue.main.async { - let wrappedError = AccountError.wrappedError(error: error, account: account) - completion(.failure(wrappedError)) - } - } - } - } else { - if let account = container as? Account { - account.removeWebFeed(feed) - } - completion(.success(())) - } - - } - } diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift index 805fd3b8d..2b829b5e9 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift @@ -358,21 +358,19 @@ final class ReaderAPICaller: NSObject { self.requestAuthorizationToken(endpoint: baseURL) { (result) in switch result { case .success(let token): - let url = baseURL + let callURL = baseURL .appendingPathComponent(ReaderAPIEndpoints.subscriptionAdd.rawValue) - .appendingQueryItem(URLQueryItem(name: "quickadd", value: url)) - - guard let callURL = url else { - completion(.failure(TransportError.noURL)) - return - } var request = URLRequest(url: callURL, credentials: self.credentials) self.addVariantHeaders(&request) request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" - - let postData = "T=\(token)".data(using: String.Encoding.utf8) + + guard let encodedFeedURL = self.encodeForURLPath(url) else { + completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) + return + } + let postData = "T=\(token)&quickadd=\(encodedFeedURL)".data(using: String.Encoding.utf8) self.transport.send(request: request, method: HTTPMethod.post, data: postData!, resultType: ReaderAPIQuickAddResult.self, completion: { (result) in switch result { @@ -387,34 +385,7 @@ final class ReaderAPICaller: NSObject { return } - if name == nil && folder == nil { - findSubscription(streamID: streamId, completion: completion) - } else { - let callURL = baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue) - var request = URLRequest(url: callURL, credentials: self.credentials) - self.addVariantHeaders(&request) - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - request.httpMethod = "POST" - - var postString = "T=\(token)&ac=subscribe&s=\(streamId)" - if let folderName = self.encodeForURLPath(folder?.nameForDisplay) { - postString += "&a=user/-/label/\(folderName)" - } - if let name = self.encodeForURLPath(name) { - postString += "&t=\(name)" - } - - let postData = postString.data(using: String.Encoding.utf8) - self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in - switch result { - case .success: - findSubscription(streamID: streamId, completion: completion) - case .failure: - completion(.failure(AccountError.createErrorAlreadySubscribed)) - } - }) - } - + findSubscription(streamID: streamId, completion: completion) } case .failure(let error): @@ -432,42 +403,7 @@ final class ReaderAPICaller: NSObject { } func renameSubscription(subscriptionID: String, newName: String, completion: @escaping (Result) -> Void) { - guard let baseURL = apiBaseURL else { - completion(.failure(CredentialsError.incompleteCredentials)) - return - } - - self.requestAuthorizationToken(endpoint: baseURL) { (result) in - switch result { - case .success(let token): - var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials) - self.addVariantHeaders(&request) - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - request.httpMethod = "POST" - - guard let encodedNewName = self.encodeForURLPath(newName) else { - completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) - return - } - - let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&t=\(encodedNewName)".data(using: String.Encoding.utf8) - - self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in - switch result { - case .success: - completion(.success(())) - break - case .failure(let error): - completion(.failure(error)) - break - } - }) - - - case .failure(let error): - completion(.failure(error)) - } - } + changeSubscription(subscriptionID: subscriptionID, title: newName, completion: completion) } func deleteSubscription(subscriptionID: String, completion: @escaping (Result) -> Void) { @@ -504,78 +440,64 @@ final class ReaderAPICaller: NSObject { } func createTagging(subscriptionID: String, tagName: String, completion: @escaping (Result) -> Void) { - - guard let baseURL = apiBaseURL else { - completion(.failure(CredentialsError.incompleteCredentials)) - return - } - - self.requestAuthorizationToken(endpoint: baseURL) { (result) in - switch result { - case .success(let token): - var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials) - self.addVariantHeaders(&request) - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - request.httpMethod = "POST" - - guard let tagName = self.encodeForURLPath(tagName) else { - completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) - return - } - - let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&a=user/-/label/\(tagName)".data(using: String.Encoding.utf8) - - self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in - switch result { - case .success: - completion(.success(())) - break - case .failure(let error): - completion(.failure(error)) - break - } - }) - - case .failure(let error): - completion(.failure(error)) - } - } - + changeSubscription(subscriptionID: subscriptionID, addTagName: tagName, completion: completion) } func deleteTagging(subscriptionID: String, tagName: String, completion: @escaping (Result) -> Void) { - guard let baseURL = apiBaseURL else { - completion(.failure(CredentialsError.incompleteCredentials)) - return - } - - self.requestAuthorizationToken(endpoint: baseURL) { (result) in - switch result { - case .success(let token): - var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials) - self.addVariantHeaders(&request) - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - request.httpMethod = "POST" - - let tagName = "user/-/label/\(tagName)" - let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&r=\(tagName)".data(using: String.Encoding.utf8) - - self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in - switch result { - case .success: - completion(.success(())) - break - case .failure(let error): - completion(.failure(error)) - break - } - }) - - case .failure(let error): - completion(.failure(error)) - } - } + changeSubscription(subscriptionID: subscriptionID, removeTagName: tagName, completion: completion) } + + func moveSubscription(subscriptionID: String, fromTag: String, toTag: String, completion: @escaping (Result) -> Void) { + changeSubscription(subscriptionID: subscriptionID, removeTagName: fromTag, addTagName: toTag, completion: completion) + } + + private func changeSubscription(subscriptionID: String, removeTagName: String? = nil, addTagName: String? = nil, title: String? = nil, completion: @escaping (Result) -> Void) { + if removeTagName == nil && addTagName == nil && title == nil { + completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) + return + } + + guard let baseURL = apiBaseURL else { + completion(.failure(CredentialsError.incompleteCredentials)) + return + } + + self.requestAuthorizationToken(endpoint: baseURL) { (result) in + switch result { + case .success(let token): + var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials) + self.addVariantHeaders(&request) + request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") + request.httpMethod = "POST" + + var postString = "T=\(token)&s=\(subscriptionID)&ac=edit" + if let fromLabel = self.encodeForURLPath(removeTagName) { + postString += "&r=user/-/label/\(fromLabel)" + } + if let toLabel = self.encodeForURLPath(addTagName) { + postString += "&a=user/-/label/\(toLabel)" + } + if let encodedTitle = self.encodeForURLPath(title) { + postString += "&t=\(encodedTitle)" + } + let postData = postString.data(using: String.Encoding.utf8) + + self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in + switch result { + case .success: + completion(.success(())) + break + case .failure(let error): + completion(.failure(error)) + break + } + }) + + case .failure(let error): + completion(.failure(error)) + } + } + } func retrieveEntries(articleIDs: [String], completion: @escaping (Result<([ReaderAPIEntry]?), Error>) -> Void) { diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift index 41abfe4be..f156c9e19 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift @@ -51,6 +51,7 @@ struct ReaderAPIEntry: Codable { let articleID: String let title: String? + let author: String? let publishedTimestamp: Double? let crawledTimestamp: String? @@ -64,6 +65,7 @@ struct ReaderAPIEntry: Codable { enum CodingKeys: String, CodingKey { case articleID = "id" case title = "title" + case author = "author" case summary = "summary" case alternates = "alternate" case categories = "categories" From fef5be3d5edbcb69eded604c36b73fad2e5cadca Mon Sep 17 00:00:00 2001 From: Dave Marquard Date: Mon, 19 Jul 2021 12:36:46 -0700 Subject: [PATCH 2/5] fix indentation --- Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift index f156c9e19..5d8575945 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIEntry.swift @@ -51,7 +51,7 @@ struct ReaderAPIEntry: Codable { let articleID: String let title: String? - let author: String? + let author: String? let publishedTimestamp: Double? let crawledTimestamp: String? @@ -65,7 +65,7 @@ struct ReaderAPIEntry: Codable { enum CodingKeys: String, CodingKey { case articleID = "id" case title = "title" - case author = "author" + case author = "author" case summary = "summary" case alternates = "alternate" case categories = "categories" From 0c5917b4a22940171ca8b3224b02c75b9258e01f Mon Sep 17 00:00:00 2001 From: Dave Marquard Date: Mon, 19 Jul 2021 13:07:57 -0700 Subject: [PATCH 3/5] fix indentation --- .../ReaderAPI/ReaderAPIAccountDelegate.swift | 14 +-- .../Account/ReaderAPI/ReaderAPICaller.swift | 118 +++++++++--------- 2 files changed, 66 insertions(+), 66 deletions(-) diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 98ca926c7..0867976c6 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -1018,12 +1018,12 @@ private extension ReaderAPIAccountDelegate { return nil } - var authors: Set? { - guard let name = entry.author else { - return nil - } - return Set([ParsedAuthor(name: name, url: nil, avatarURL: nil, emailAddress: nil)]) - } + var authors: Set? { + guard let name = entry.author else { + return nil + } + return Set([ParsedAuthor(name: name, url: nil, avatarURL: nil, emailAddress: nil)]) + } return ParsedItem(syncServiceID: entry.uniqueID(variant: variant), uniqueID: entry.uniqueID(variant: variant), @@ -1039,7 +1039,7 @@ private extension ReaderAPIAccountDelegate { bannerImageURL: nil, datePublished: entry.parseDatePublished(), dateModified: nil, - authors: authors, + authors: authors, tags: nil, attachments: nil) } diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift index 2b829b5e9..46b8c97e1 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift @@ -360,16 +360,16 @@ final class ReaderAPICaller: NSObject { case .success(let token): let callURL = baseURL .appendingPathComponent(ReaderAPIEndpoints.subscriptionAdd.rawValue) - + var request = URLRequest(url: callURL, credentials: self.credentials) self.addVariantHeaders(&request) request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" - - guard let encodedFeedURL = self.encodeForURLPath(url) else { - completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) - return - } + + guard let encodedFeedURL = self.encodeForURLPath(url) else { + completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) + return + } let postData = "T=\(token)&quickadd=\(encodedFeedURL)".data(using: String.Encoding.utf8) self.transport.send(request: request, method: HTTPMethod.post, data: postData!, resultType: ReaderAPIQuickAddResult.self, completion: { (result) in @@ -442,62 +442,62 @@ final class ReaderAPICaller: NSObject { func createTagging(subscriptionID: String, tagName: String, completion: @escaping (Result) -> Void) { changeSubscription(subscriptionID: subscriptionID, addTagName: tagName, completion: completion) } - + func deleteTagging(subscriptionID: String, tagName: String, completion: @escaping (Result) -> Void) { changeSubscription(subscriptionID: subscriptionID, removeTagName: tagName, completion: completion) } - - func moveSubscription(subscriptionID: String, fromTag: String, toTag: String, completion: @escaping (Result) -> Void) { - changeSubscription(subscriptionID: subscriptionID, removeTagName: fromTag, addTagName: toTag, completion: completion) - } - - private func changeSubscription(subscriptionID: String, removeTagName: String? = nil, addTagName: String? = nil, title: String? = nil, completion: @escaping (Result) -> Void) { - if removeTagName == nil && addTagName == nil && title == nil { - completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) - return - } - - guard let baseURL = apiBaseURL else { - completion(.failure(CredentialsError.incompleteCredentials)) - return - } - - self.requestAuthorizationToken(endpoint: baseURL) { (result) in - switch result { - case .success(let token): - var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials) - self.addVariantHeaders(&request) - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - request.httpMethod = "POST" - - var postString = "T=\(token)&s=\(subscriptionID)&ac=edit" - if let fromLabel = self.encodeForURLPath(removeTagName) { - postString += "&r=user/-/label/\(fromLabel)" - } - if let toLabel = self.encodeForURLPath(addTagName) { - postString += "&a=user/-/label/\(toLabel)" - } - if let encodedTitle = self.encodeForURLPath(title) { - postString += "&t=\(encodedTitle)" - } - let postData = postString.data(using: String.Encoding.utf8) - - self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in - switch result { - case .success: - completion(.success(())) - break - case .failure(let error): - completion(.failure(error)) - break - } - }) - - case .failure(let error): - completion(.failure(error)) - } - } - } + + func moveSubscription(subscriptionID: String, fromTag: String, toTag: String, completion: @escaping (Result) -> Void) { + changeSubscription(subscriptionID: subscriptionID, removeTagName: fromTag, addTagName: toTag, completion: completion) + } + + private func changeSubscription(subscriptionID: String, removeTagName: String? = nil, addTagName: String? = nil, title: String? = nil, completion: @escaping (Result) -> Void) { + if removeTagName == nil && addTagName == nil && title == nil { + completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) + return + } + + guard let baseURL = apiBaseURL else { + completion(.failure(CredentialsError.incompleteCredentials)) + return + } + + self.requestAuthorizationToken(endpoint: baseURL) { (result) in + switch result { + case .success(let token): + var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials) + self.addVariantHeaders(&request) + request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") + request.httpMethod = "POST" + + var postString = "T=\(token)&s=\(subscriptionID)&ac=edit" + if let fromLabel = self.encodeForURLPath(removeTagName) { + postString += "&r=user/-/label/\(fromLabel)" + } + if let toLabel = self.encodeForURLPath(addTagName) { + postString += "&a=user/-/label/\(toLabel)" + } + if let encodedTitle = self.encodeForURLPath(title) { + postString += "&t=\(encodedTitle)" + } + let postData = postString.data(using: String.Encoding.utf8) + + self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in + switch result { + case .success: + completion(.success(())) + break + case .failure(let error): + completion(.failure(error)) + break + } + }) + + case .failure(let error): + completion(.failure(error)) + } + } + } func retrieveEntries(articleIDs: [String], completion: @escaping (Result<([ReaderAPIEntry]?), Error>) -> Void) { From 17759255e736aec0a39b51a68a589da39579c065 Mon Sep 17 00:00:00 2001 From: Dave Marquard Date: Mon, 19 Jul 2021 13:16:26 -0700 Subject: [PATCH 4/5] more indentation --- .../ReaderAPI/ReaderAPIAccountDelegate.swift | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 0867976c6..812085fbe 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -473,23 +473,27 @@ final class ReaderAPIAccountDelegate: AccountDelegate { if from is Account { addWebFeed(for: account, with: feed, to: to, completion: completion) } else { - guard let subscriptionId = feed.externalID, let fromTag = (from as? Folder)?.name, let toTag = (to as? Folder)?.name else { - completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) - return - } - - refreshProgress.addToNumberOfTasksAndRemaining(1) - caller.moveSubscription(subscriptionID: subscriptionId, fromTag: fromTag, toTag: toTag) { result in - self.refreshProgress.completeTask() - switch result { - case .success: - from.removeWebFeed(feed) - to.addWebFeed(feed) - completion(.success(())) - case .failure(let error): - completion(.failure(error)) - } - } + guard + let subscriptionId = feed.externalID, + let fromTag = (from as? Folder)?.name, + let toTag = (to as? Folder)?.name + else { + completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) + return + } + + refreshProgress.addToNumberOfTasksAndRemaining(1) + caller.moveSubscription(subscriptionID: subscriptionId, fromTag: fromTag, toTag: toTag) { result in + self.refreshProgress.completeTask() + switch result { + case .success: + from.removeWebFeed(feed) + to.addWebFeed(feed) + completion(.success(())) + case .failure(let error): + completion(.failure(error)) + } + } } } From 57ccaeac70fb82a74072619e8225e396e1488169 Mon Sep 17 00:00:00 2001 From: Dave Marquard Date: Mon, 19 Jul 2021 13:22:02 -0700 Subject: [PATCH 5/5] minor style change --- Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift index 46b8c97e1..a769d956c 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift @@ -452,7 +452,7 @@ final class ReaderAPICaller: NSObject { } private func changeSubscription(subscriptionID: String, removeTagName: String? = nil, addTagName: String? = nil, title: String? = nil, completion: @escaping (Result) -> Void) { - if removeTagName == nil && addTagName == nil && title == nil { + guard removeTagName != nil || addTagName != nil || title != nil else { completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) return }