Continue adopting async/await. Also: rename some Ids to IDs.

This commit is contained in:
Brent Simmons
2023-07-12 20:33:49 -07:00
parent 2a18cd8930
commit 9bbecc99c7
22 changed files with 127 additions and 130 deletions

View File

@@ -898,6 +898,8 @@ public enum FetchType {
noteStatusesForArticleIDsDidChange(articleIDs: articleIDs, statusKey: statusKey, flag: flag)
}
/// Mark articleIDs as read. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Returns a set of new article statuses.
func markArticleIDsAsRead(_ articleIDs: Set<String>) async throws {
try await markArticleIDs(articleIDs, statusKey: .read, flag: true)
}
@@ -908,19 +910,37 @@ public enum FetchType {
mark(articleIDs: articleIDs, statusKey: .read, flag: true, completion: completion)
}
/// Mark articleIDs as unread. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Mark articleIDs as unread. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Returns a set of new article statuses.
func markArticleIDsAsUnread(_ articleIDs: Set<String>) async throws {
try await markArticleIDs(articleIDs, statusKey: .read, flag: false)
}
/// Mark articleIDs as unread. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Returns a set of new article statuses.
func markAsUnread(_ articleIDs: Set<String>, completion: DatabaseCompletionBlock? = nil) {
mark(articleIDs: articleIDs, statusKey: .read, flag: false, completion: completion)
}
/// Mark articleIDs as starred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Mark articleIDs as starred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Returns a set of new article statuses.
func markArticleIDsAsStarred(_ articleIDs: Set<String>) async throws {
try await markArticleIDs(articleIDs, statusKey: .starred, flag: true)
}
/// Mark articleIDs as starred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Returns a set of new article statuses.
func markAsStarred(_ articleIDs: Set<String>, completion: DatabaseCompletionBlock? = nil) {
mark(articleIDs: articleIDs, statusKey: .starred, flag: true, completion: completion)
}
/// Mark articleIDs as unstarred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Mark articleIDs as unstarred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Returns a set of new article statuses.
func markArticleIDsAsUnstarred(_ articleIDs: Set<String>) async throws {
try await markArticleIDs(articleIDs, statusKey: .starred, flag: false)
}
/// Mark articleIDs as unstarred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
/// Returns a set of new article statuses.
func markAsUnstarred(_ articleIDs: Set<String>, completion: DatabaseCompletionBlock? = nil) {
mark(articleIDs: articleIDs, statusKey: .starred, flag: false, completion: completion)

View File

@@ -671,9 +671,9 @@ extension FeedlyAPICaller: FeedlyGetStreamContentsService {
}
}
extension FeedlyAPICaller: FeedlyGetStreamIdsService {
extension FeedlyAPICaller: FeedlyGetStreamIDsService {
func getStreamIds(for resource: FeedlyResourceId, continuation: String? = nil, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIds, Error>) -> ()) {
func streamIDs(for resource: FeedlyResourceId, continuation: String? = nil, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIDs, Error>) -> ()) {
guard !isSuspended else {
return DispatchQueue.main.async {
completion(.failure(TransportError.suspended))
@@ -724,7 +724,7 @@ extension FeedlyAPICaller: FeedlyGetStreamIdsService {
request.addValue("application/json", forHTTPHeaderField: "Accept-Type")
request.addValue("OAuth \(accessToken)", forHTTPHeaderField: HTTPRequestHeader.authorization)
send(request: request, resultType: FeedlyStreamIds.self, dateDecoding: .millisecondsSince1970, keyDecoding: .convertFromSnakeCase) { result in
send(request: request, resultType: FeedlyStreamIDs.self, dateDecoding: .millisecondsSince1970, keyDecoding: .convertFromSnakeCase) { result in
switch result {
case .success(let (_, collections)):
if let response = collections {

View File

@@ -186,7 +186,7 @@ final class FeedlyAccountDelegate: AccountDelegate, Logging {
let group = DispatchGroup()
let ingestUnread = FeedlyIngestUnreadArticleIdsOperation(account: account, userId: credentials.username, service: caller, database: database, newerThan: nil)
let ingestUnread = FeedlyIngestUnreadArticleIdsOperation(account: account, userID: credentials.username, service: caller, database: database, newerThan: nil)
group.enter()
ingestUnread.completionBlock = { _ in

View File

@@ -44,29 +44,29 @@ extension FeedlyFeedResourceId {
}
}
struct FeedlyCategoryResourceId: FeedlyResourceId {
struct FeedlyCategoryResourceID: FeedlyResourceId {
let id: String
enum Global {
static func uncategorized(for userId: String) -> FeedlyCategoryResourceId {
static func uncategorized(for userId: String) -> FeedlyCategoryResourceID {
// https://developer.feedly.com/cloud/#global-resource-ids
let id = "user/\(userId)/category/global.uncategorized"
return FeedlyCategoryResourceId(id: id)
return FeedlyCategoryResourceID(id: id)
}
/// All articles from all the feeds the user subscribes to.
static func all(for userId: String) -> FeedlyCategoryResourceId {
static func all(for userId: String) -> FeedlyCategoryResourceID {
// https://developer.feedly.com/cloud/#global-resource-ids
let id = "user/\(userId)/category/global.all"
return FeedlyCategoryResourceId(id: id)
return FeedlyCategoryResourceID(id: id)
}
/// All articles from all the feeds the user loves most.
static func mustRead(for userId: String) -> FeedlyCategoryResourceId {
static func mustRead(for userId: String) -> FeedlyCategoryResourceID {
// https://developer.feedly.com/cloud/#global-resource-ids
let id = "user/\(userId)/category/global.must"
return FeedlyCategoryResourceId(id: id)
return FeedlyCategoryResourceID(id: id)
}
}
}

View File

@@ -1,5 +1,5 @@
//
// FeedlyStreamIds.swift
// FeedlyStreamIDs.swift
// Account
//
// Created by Kiel Gillard on 18/10/19.
@@ -8,7 +8,7 @@
import Foundation
struct FeedlyStreamIds: Decodable {
struct FeedlyStreamIDs: Decodable {
let continuation: String?
let ids: [String]

View File

@@ -23,12 +23,12 @@ class FeedlyAddNewFeedOperation: FeedlyOperation, FeedlyOperationDelegate, Feedl
private let database: SyncDatabase
private let feedName: String?
private let addToCollectionService: FeedlyAddFeedToCollectionService
private let syncUnreadIdsService: FeedlyGetStreamIdsService
private let syncUnreadIdsService: FeedlyGetStreamIDsService
private let getStreamContentsService: FeedlyGetStreamContentsService
private var feedResourceId: FeedlyFeedResourceId?
var addCompletionHandler: ((Result<Feed, Error>) -> ())?
init(account: Account, credentials: Credentials, url: String, feedName: String?, searchService: FeedlySearchService, addToCollectionService: FeedlyAddFeedToCollectionService, syncUnreadIdsService: FeedlyGetStreamIdsService, getStreamContentsService: FeedlyGetStreamContentsService, database: SyncDatabase, container: Container, progress: DownloadProgress) throws {
init(account: Account, credentials: Credentials, url: String, feedName: String?, searchService: FeedlySearchService, addToCollectionService: FeedlyAddFeedToCollectionService, syncUnreadIdsService: FeedlyGetStreamIDsService, getStreamContentsService: FeedlyGetStreamContentsService, database: SyncDatabase, container: Container, progress: DownloadProgress) throws {
let validator = FeedlyFeedContainerValidator(container: container)
@@ -94,7 +94,7 @@ class FeedlyAddNewFeedOperation: FeedlyOperation, FeedlyOperationDelegate, Feedl
createFeeds.downloadProgress = downloadProgress
operationQueue.add(createFeeds)
let syncUnread = FeedlyIngestUnreadArticleIdsOperation(account: account, userId: credentials.username, service: syncUnreadIdsService, database: database, newerThan: nil)
let syncUnread = FeedlyIngestUnreadArticleIdsOperation(account: account, userID: credentials.username, service: syncUnreadIdsService, database: database, newerThan: nil)
syncUnread.addDependency(createFeeds)
syncUnread.downloadProgress = downloadProgress
syncUnread.delegate = self

View File

@@ -1,5 +1,5 @@
//
// FeedlyGetStreamIdsOperation.swift
// FeedlyGetStreamIDsOperation.swift
// Account
//
// Created by Kiel Gillard on 18/10/19.
@@ -10,7 +10,7 @@ import Foundation
import RSCore
protocol FeedlyGetStreamIdsOperationDelegate: AnyObject {
func feedlyGetStreamIdsOperation(_ operation: FeedlyGetStreamIdsOperation, didGet streamIds: FeedlyStreamIds)
func feedlyGetStreamIdsOperation(_ operation: FeedlyGetStreamIdsOperation, didGet streamIds: FeedlyStreamIDs)
}
/// Single responsibility is to get the stream ids from Feedly.
@@ -24,16 +24,16 @@ final class FeedlyGetStreamIdsOperation: FeedlyOperation, FeedlyEntryIdentifierP
return Set(ids)
}
private(set) var streamIds: FeedlyStreamIds?
private(set) var streamIds: FeedlyStreamIDs?
let account: Account
let service: FeedlyGetStreamIdsService
let service: FeedlyGetStreamIDsService
let continuation: String?
let resource: FeedlyResourceId
let unreadOnly: Bool?
let newerThan: Date?
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIdsService, continuation: String? = nil, newerThan: Date? = nil, unreadOnly: Bool?) {
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIDsService, continuation: String? = nil, newerThan: Date? = nil, unreadOnly: Bool?) {
self.account = account
self.resource = resource
self.service = service
@@ -45,7 +45,7 @@ final class FeedlyGetStreamIdsOperation: FeedlyOperation, FeedlyEntryIdentifierP
weak var streamIdsDelegate: FeedlyGetStreamIdsOperationDelegate?
override func run() {
service.getStreamIds(for: resource, continuation: continuation, newerThan: newerThan, unreadOnly: unreadOnly) { result in
service.streamIDs(for: resource, continuation: continuation, newerThan: newerThan, unreadOnly: unreadOnly) { result in
switch result {
case .success(let stream):
self.streamIds = stream

View File

@@ -18,18 +18,18 @@ class FeedlyGetUpdatedArticleIdsOperation: FeedlyOperation, FeedlyEntryIdentifie
private let account: Account
private let resource: FeedlyResourceId
private let service: FeedlyGetStreamIdsService
private let service: FeedlyGetStreamIDsService
private let newerThan: Date?
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIdsService, newerThan: Date?) {
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIDsService, newerThan: Date?) {
self.account = account
self.resource = resource
self.service = service
self.newerThan = newerThan
}
convenience init(account: Account, userId: String, service: FeedlyGetStreamIdsService, newerThan: Date?) {
let all = FeedlyCategoryResourceId.Global.all(for: userId)
convenience init(account: Account, userId: String, service: FeedlyGetStreamIDsService, newerThan: Date?) {
let all = FeedlyCategoryResourceID.Global.all(for: userId)
self.init(account: account, resource: all, service: service, newerThan: newerThan)
}
@@ -50,10 +50,10 @@ class FeedlyGetUpdatedArticleIdsOperation: FeedlyOperation, FeedlyEntryIdentifie
return
}
service.getStreamIds(for: resource, continuation: continuation, newerThan: date, unreadOnly: nil, completion: didGetStreamIds(_:))
service.streamIDs(for: resource, continuation: continuation, newerThan: date, unreadOnly: nil, completion: didGetStreamIds(_:))
}
private func didGetStreamIds(_ result: Result<FeedlyStreamIds, Error>) {
private func didGetStreamIds(_ result: Result<FeedlyStreamIDs, Error>) {
guard !isCanceled else {
didFinish()
return
@@ -72,7 +72,7 @@ class FeedlyGetUpdatedArticleIdsOperation: FeedlyOperation, FeedlyEntryIdentifie
getStreamIds(continuation)
case .failure(let error):
self.logger.error("Error getting FeedlyStreamIds: \(error.localizedDescription, privacy: .public).")
self.logger.error("Error getting FeedlyStreamIDs: \(error.localizedDescription, privacy: .public).")
didFinish(with: error)
}
}

View File

@@ -21,16 +21,16 @@ final class FeedlyIngestStarredArticleIdsOperation: FeedlyOperation, Logging {
private let account: Account
private let resource: FeedlyResourceId
private let service: FeedlyGetStreamIdsService
private let service: FeedlyGetStreamIDsService
private let database: SyncDatabase
private var remoteEntryIds = Set<String>()
convenience init(account: Account, userId: String, service: FeedlyGetStreamIdsService, database: SyncDatabase, newerThan: Date?) {
convenience init(account: Account, userId: String, service: FeedlyGetStreamIDsService, database: SyncDatabase, newerThan: Date?) {
let resource = FeedlyTagResourceId.Global.saved(for: userId)
self.init(account: account, resource: resource, service: service, database: database, newerThan: newerThan)
}
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIdsService, database: SyncDatabase, newerThan: Date?) {
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIDsService, database: SyncDatabase, newerThan: Date?) {
self.account = account
self.resource = resource
self.service = service
@@ -42,10 +42,10 @@ final class FeedlyIngestStarredArticleIdsOperation: FeedlyOperation, Logging {
}
private func getStreamIds(_ continuation: String?) {
service.getStreamIds(for: resource, continuation: continuation, newerThan: nil, unreadOnly: nil, completion: didGetStreamIds(_:))
service.streamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: nil, completion: didGetStreamIds(_:))
}
private func didGetStreamIds(_ result: Result<FeedlyStreamIds, Error>) {
private func didGetStreamIds(_ result: Result<FeedlyStreamIDs, Error>) {
guard !isCanceled else {
didFinish()
return

View File

@@ -19,16 +19,16 @@ class FeedlyIngestStreamArticleIdsOperation: FeedlyOperation, Logging {
private let account: Account
private let resource: FeedlyResourceId
private let service: FeedlyGetStreamIdsService
private let service: FeedlyGetStreamIDsService
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIdsService) {
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIDsService) {
self.account = account
self.resource = resource
self.service = service
}
convenience init(account: Account, userId: String, service: FeedlyGetStreamIdsService) {
let all = FeedlyCategoryResourceId.Global.all(for: userId)
convenience init(account: Account, userId: String, service: FeedlyGetStreamIDsService) {
let all = FeedlyCategoryResourceID.Global.all(for: userId)
self.init(account: account, resource: all, service: service)
}
@@ -37,10 +37,10 @@ class FeedlyIngestStreamArticleIdsOperation: FeedlyOperation, Logging {
}
private func getStreamIds(_ continuation: String?) {
service.getStreamIds(for: resource, continuation: continuation, newerThan: nil, unreadOnly: nil, completion: didGetStreamIds(_:))
service.streamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: nil, completion: didGetStreamIds(_:))
}
private func didGetStreamIds(_ result: Result<FeedlyStreamIds, Error>) {
private func didGetStreamIds(_ result: Result<FeedlyStreamIDs, Error>) {
guard !isCanceled else {
didFinish()
return

View File

@@ -4,7 +4,7 @@
//
// Created by Kiel Gillard on 18/10/19.
// Copyright © 2019 Ranchero Software, LLC. All rights reserved.
//
///Users/brent/Projects/NetNewsWire/Account/Sources/Account/Feedly/Operations/FeedlyIngestUnreadArticleIDsOperation.swift
import Foundation
import RSCore
@@ -22,16 +22,16 @@ final class FeedlyIngestUnreadArticleIdsOperation: FeedlyOperation, Logging {
private let account: Account
private let resource: FeedlyResourceId
private let service: FeedlyGetStreamIdsService
private let service: FeedlyGetStreamIDsService
private let database: SyncDatabase
private var remoteEntryIds = Set<String>()
private var remoteEntryIDs = Set<String>()
convenience init(account: Account, userId: String, service: FeedlyGetStreamIdsService, database: SyncDatabase, newerThan: Date?) {
let resource = FeedlyCategoryResourceId.Global.all(for: userId)
convenience init(account: Account, userID: String, service: FeedlyGetStreamIDsService, database: SyncDatabase, newerThan: Date?) {
let resource = FeedlyCategoryResourceID.Global.all(for: userID)
self.init(account: account, resource: resource, service: service, database: database, newerThan: newerThan)
}
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIdsService, database: SyncDatabase, newerThan: Date?) {
init(account: Account, resource: FeedlyResourceId, service: FeedlyGetStreamIDsService, database: SyncDatabase, newerThan: Date?) {
self.account = account
self.resource = resource
self.service = service
@@ -39,30 +39,30 @@ final class FeedlyIngestUnreadArticleIdsOperation: FeedlyOperation, Logging {
}
override func run() {
getStreamIds(nil)
getStreamIDs(nil)
}
private func getStreamIds(_ continuation: String?) {
service.getStreamIds(for: resource, continuation: continuation, newerThan: nil, unreadOnly: true, completion: didGetStreamIds(_:))
private func getStreamIDs(_ continuation: String?) {
service.streamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: true, completion: didGetStreamIDs(_:))
}
private func didGetStreamIds(_ result: Result<FeedlyStreamIds, Error>) {
private func didGetStreamIDs(_ result: Result<FeedlyStreamIDs, Error>) {
guard !isCanceled else {
didFinish()
return
}
switch result {
case .success(let streamIds):
case .success(let streamIDs):
remoteEntryIds.formUnion(streamIds.ids)
remoteEntryIDs.formUnion(streamIDs.ids)
guard let continuation = streamIds.continuation else {
removeEntryIdsWithPendingStatus()
guard let continuation = streamIDs.continuation else {
removeEntryIDsWithPendingStatus()
return
}
getStreamIds(continuation)
getStreamIDs(continuation)
case .failure(let error):
didFinish(with: error)
@@ -70,7 +70,7 @@ final class FeedlyIngestUnreadArticleIdsOperation: FeedlyOperation, Logging {
}
/// Do not override pending statuses with the remote statuses of the same articles, otherwise an article will temporarily re-acquire the remote status before the pending status is pushed and subseqently pulled.
private func removeEntryIdsWithPendingStatus() {
private func removeEntryIDsWithPendingStatus() {
guard !isCanceled else {
didFinish()
return
@@ -78,8 +78,8 @@ final class FeedlyIngestUnreadArticleIdsOperation: FeedlyOperation, Logging {
database.selectPendingReadStatusArticleIDs { result in
switch result {
case .success(let pendingArticleIds):
self.remoteEntryIds.subtract(pendingArticleIds)
case .success(let pendingArticleIDs):
self.remoteEntryIDs.subtract(pendingArticleIDs)
self.updateUnreadStatuses()
@@ -106,51 +106,28 @@ final class FeedlyIngestUnreadArticleIdsOperation: FeedlyOperation, Logging {
}
if let localUnreadArticleIDs {
processUnreadArticleIDs(localUnreadArticleIDs)
await processUnreadArticleIDs(localUnreadArticleIDs)
}
}
}
private func processUnreadArticleIDs(_ localUnreadArticleIDs: Set<String>) {
guard !isCanceled else {
didFinish()
return
}
@MainActor private func processUnreadArticleIDs(_ localUnreadArticleIDs: Set<String>) async {
guard !isCanceled else {
didFinish()
return
}
let remoteUnreadArticleIDs = remoteEntryIds
let group = DispatchGroup()
final class ReadStatusResults {
var markAsUnreadError: Error?
var markAsReadError: Error?
}
let results = ReadStatusResults()
group.enter()
account.markAsUnread(remoteUnreadArticleIDs) { databaseError in
if let databaseError = databaseError {
results.markAsUnreadError = databaseError
}
group.leave()
}
let remoteUnreadArticleIDs = remoteEntryIDs
let articleIDsToMarkRead = localUnreadArticleIDs.subtracting(remoteUnreadArticleIDs)
group.enter()
account.markAsRead(articleIDsToMarkRead) { databaseError in
if let databaseError = databaseError {
results.markAsReadError = databaseError
}
group.leave()
}
do {
try await account.markArticleIDsAsUnread(remoteUnreadArticleIDs)
group.notify(queue: .main) {
let markingError = results.markAsReadError ?? results.markAsUnreadError
guard let error = markingError else {
self.didFinish()
return
}
self.didFinish(with: error)
}
let articleIDsToMarkRead = localUnreadArticleIDs.subtracting(remoteUnreadArticleIDs)
try await account.markArticleIDsAsRead(articleIDsToMarkRead)
didFinish()
} catch let error {
didFinish(with: error)
}
}
}

View File

@@ -43,7 +43,7 @@ final class FeedlyRequestStreamsOperation: FeedlyOperation, Logging {
// TODO: Prioritise the must read collection/category before others so the most important content for the user loads first.
for collection in collectionsProvider.collections {
let resource = FeedlyCategoryResourceId(id: collection.id)
let resource = FeedlyCategoryResourceID(id: collection.id)
let operation = FeedlyGetStreamContentsOperation(account: account,
resource: resource,
service: service,

View File

@@ -32,7 +32,7 @@ final class FeedlySyncAllOperation: FeedlyOperation, Logging {
///
/// Download articles for statuses at the union of those statuses without its corresponding article and those included in 3 (changed since last successful sync).
///
init(account: Account, feedlyUserId: String, lastSuccessfulFetchStartDate: Date?, markArticlesService: FeedlyMarkArticlesService, getUnreadService: FeedlyGetStreamIdsService, getCollectionsService: FeedlyGetCollectionsService, getStreamContentsService: FeedlyGetStreamContentsService, getStarredService: FeedlyGetStreamIdsService, getStreamIdsService: FeedlyGetStreamIdsService, getEntriesService: FeedlyGetEntriesService, database: SyncDatabase, downloadProgress: DownloadProgress) {
init(account: Account, feedlyUserId: String, lastSuccessfulFetchStartDate: Date?, markArticlesService: FeedlyMarkArticlesService, getUnreadService: FeedlyGetStreamIDsService, getCollectionsService: FeedlyGetCollectionsService, getStreamContentsService: FeedlyGetStreamContentsService, getStarredService: FeedlyGetStreamIDsService, getStreamIdsService: FeedlyGetStreamIDsService, getEntriesService: FeedlyGetEntriesService, database: SyncDatabase, downloadProgress: DownloadProgress) {
self.syncUUID = UUID()
self.operationQueue.suspend()
@@ -72,7 +72,7 @@ final class FeedlySyncAllOperation: FeedlyOperation, Logging {
self.operationQueue.add(getAllArticleIds)
// Get each page of unread article ids in the global.all stream for the last 31 days (nil = Feedly API default).
let getUnread = FeedlyIngestUnreadArticleIdsOperation(account: account, userId: feedlyUserId, service: getUnreadService, database: database, newerThan: nil)
let getUnread = FeedlyIngestUnreadArticleIdsOperation(account: account, userID: feedlyUserId, service: getUnreadService, database: database, newerThan: nil)
getUnread.delegate = self
getUnread.addDependency(getAllArticleIds)
getUnread.downloadProgress = downloadProgress

View File

@@ -39,7 +39,7 @@ final class FeedlySyncStreamContentsOperation: FeedlyOperation, FeedlyOperationD
}
convenience init(account: Account, credentials: Credentials, service: FeedlyGetStreamContentsService, newerThan: Date?) {
let all = FeedlyCategoryResourceId.Global.all(for: credentials.username)
let all = FeedlyCategoryResourceID.Global.all(for: credentials.username)
self.init(account: account, resource: all, service: service, isPagingEnabled: true, newerThan: newerThan)
}

View File

@@ -1,5 +1,5 @@
//
// FeedlyGetStreamIdsService.swift
// FeedlyGetStreamIDsService.swift
// Account
//
// Created by Kiel Gillard on 21/10/19.
@@ -8,6 +8,6 @@
import Foundation
protocol FeedlyGetStreamIdsService: AnyObject {
func getStreamIds(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIds, Error>) -> ())
protocol FeedlyGetStreamIDsService: AnyObject {
func streamIDs(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIDs, Error>) -> ())
}

View File

@@ -334,7 +334,7 @@ extension NewsBlurAccountDelegate {
// Mark articles as unread
let deltaUnreadArticleIDs = updatableNewsBlurUnreadStoryHashes.subtracting(currentUnreadArticleIDs)
account.markAsUnread(deltaUnreadArticleIDs)
try await account.markArticleIDsAsUnread(deltaUnreadArticleIDs)
// Mark articles as read
let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(updatableNewsBlurUnreadStoryHashes)

View File

@@ -29,7 +29,7 @@ class FeedlyGetStreamContentsOperationTests: XCTestCase {
func testGetStreamContentsFailure() {
let service = TestGetStreamContentsService()
let resource = FeedlyCategoryResourceId(id: "user/1234/category/5678")
let resource = FeedlyCategoryResourceID(id: "user/1234/category/5678")
let getStreamContents = FeedlyGetStreamContentsOperation(account: account, resource: resource, service: service, continuation: nil, newerThan: nil, unreadOnly: nil, log: support.log)
@@ -49,7 +49,7 @@ class FeedlyGetStreamContentsOperationTests: XCTestCase {
func testValuesPassingForGetStreamContents() {
let service = TestGetStreamContentsService()
let resource = FeedlyCategoryResourceId(id: "user/1234/category/5678")
let resource = FeedlyCategoryResourceID(id: "user/1234/category/5678")
let continuation: String? = "abcdefg"
let newerThan: Date? = Date(timeIntervalSinceReferenceDate: 86)
@@ -97,7 +97,7 @@ class FeedlyGetStreamContentsOperationTests: XCTestCase {
let jsonName = "JSON/feedly_macintosh_initial"
transport.testFiles["/v3/streams/contents"] = "\(jsonName).json"
let resource = FeedlyCategoryResourceId(id: "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/5ca4d61d-e55d-4999-a8d1-c3b9d8789815")
let resource = FeedlyCategoryResourceID(id: "user/f2f031bd-f3e3-4893-a447-467a291c6d1e/category/5ca4d61d-e55d-4999-a8d1-c3b9d8789815")
let getStreamContents = FeedlyGetStreamContentsOperation(account: account, resource: resource, service: caller, continuation: nil, newerThan: nil, unreadOnly: nil, log: support.log)
let completionExpectation = expectation(description: "Did Finish")

View File

@@ -29,7 +29,7 @@ class FeedlyGetStreamIdsOperationTests: XCTestCase {
func testGetStreamIdsFailure() {
let service = TestGetStreamIdsService()
let resource = FeedlyCategoryResourceId(id: "user/1234/category/5678")
let resource = FeedlyCategoryResourceID(id: "user/1234/category/5678")
let getStreamIds = FeedlyGetStreamIdsOperation(account: account, resource: resource, service: service, continuation: nil, newerThan: nil, unreadOnly: nil, log: support.log)
@@ -49,7 +49,7 @@ class FeedlyGetStreamIdsOperationTests: XCTestCase {
func testValuesPassingForGetStreamIds() {
let service = TestGetStreamIdsService()
let resource = FeedlyCategoryResourceId(id: "user/1234/category/5678")
let resource = FeedlyCategoryResourceID(id: "user/1234/category/5678")
let continuation: String? = "gfdsa"
let newerThan: Date? = Date(timeIntervalSinceReferenceDate: 1000)
@@ -57,7 +57,7 @@ class FeedlyGetStreamIdsOperationTests: XCTestCase {
let getStreamIds = FeedlyGetStreamIdsOperation(account: account, resource: resource, service: service, continuation: continuation, newerThan: newerThan, unreadOnly: unreadOnly, log: support.log)
let mockStreamIds = FeedlyStreamIds(continuation: "1234", ids: ["item/1", "item/2", "item/3"])
let mockStreamIds = FeedlyStreamIDs(continuation: "1234", ids: ["item/1", "item/2", "item/3"])
service.mockResult = .success(mockStreamIds)
service.getStreamIdsExpectation = expectation(description: "Did Call Service")
service.parameterTester = { serviceResource, serviceContinuation, serviceNewerThan, serviceUnreadOnly in
@@ -92,7 +92,7 @@ class FeedlyGetStreamIdsOperationTests: XCTestCase {
let jsonName = "JSON/feedly_unreads_1000"
transport.testFiles["/v3/streams/ids"] = "\(jsonName).json"
let resource = FeedlyCategoryResourceId(id: "user/1234/category/5678")
let resource = FeedlyCategoryResourceID(id: "user/1234/category/5678")
let getStreamIds = FeedlyGetStreamIdsOperation(account: account, resource: resource, service: caller, continuation: nil, newerThan: nil, unreadOnly: nil, log: support.log)
let completionExpectation = expectation(description: "Did Finish")

View File

@@ -36,7 +36,7 @@ class FeedlyOrganiseParsedItemsByFeedOperationTests: XCTestCase {
func testNoEntries() {
let entries = support.makeParsedItemTestDataFor(numberOfFeeds: 0, numberOfItemsInFeeds: 0)
let resource = FeedlyCategoryResourceId(id: "user/12345/category/6789")
let resource = FeedlyCategoryResourceID(id: "user/12345/category/6789")
let parsedEntries = Set(entries.values.flatMap { $0 })
let provider = TestParsedItemsProvider(resource: resource, parsedEntries: parsedEntries)
@@ -57,7 +57,7 @@ class FeedlyOrganiseParsedItemsByFeedOperationTests: XCTestCase {
func testGroupsOneEntryByFeedId() {
let entries = support.makeParsedItemTestDataFor(numberOfFeeds: 1, numberOfItemsInFeeds: 1)
let resource = FeedlyCategoryResourceId(id: "user/12345/category/6789")
let resource = FeedlyCategoryResourceID(id: "user/12345/category/6789")
let parsedEntries = Set(entries.values.flatMap { $0 })
let provider = TestParsedItemsProvider(resource: resource, parsedEntries: parsedEntries)
@@ -78,7 +78,7 @@ class FeedlyOrganiseParsedItemsByFeedOperationTests: XCTestCase {
func testGroupsManyEntriesByFeedId() {
let entries = support.makeParsedItemTestDataFor(numberOfFeeds: 100, numberOfItemsInFeeds: 100)
let resource = FeedlyCategoryResourceId(id: "user/12345/category/6789")
let resource = FeedlyCategoryResourceID(id: "user/12345/category/6789")
let parsedEntries = Set(entries.values.flatMap { $0 })
let provider = TestParsedItemsProvider(resource: resource, parsedEntries: parsedEntries)

View File

@@ -29,7 +29,7 @@ class FeedlySyncStreamContentsOperationTests: XCTestCase {
func testIngestsOnePageSuccess() throws {
let service = TestGetStreamContentsService()
let resource = FeedlyCategoryResourceId(id: "user/1234/category/5678")
let resource = FeedlyCategoryResourceID(id: "user/1234/category/5678")
let newerThan: Date? = Date(timeIntervalSinceReferenceDate: 0)
let items = service.makeMockFeedlyEntryItem()
service.mockResult = .success(FeedlyStream(id: resource.id, updated: nil, continuation: nil, items: items))
@@ -63,7 +63,7 @@ class FeedlySyncStreamContentsOperationTests: XCTestCase {
func testIngestsOnePageFailure() {
let service = TestGetStreamContentsService()
let resource = FeedlyCategoryResourceId(id: "user/1234/category/5678")
let resource = FeedlyCategoryResourceID(id: "user/1234/category/5678")
let newerThan: Date? = Date(timeIntervalSinceReferenceDate: 0)
service.mockResult = .failure(URLError(.timedOut))
@@ -93,7 +93,7 @@ class FeedlySyncStreamContentsOperationTests: XCTestCase {
func testIngestsManyPagesSuccess() throws {
let service = TestGetPagedStreamContentsService()
let resource = FeedlyCategoryResourceId(id: "user/1234/category/5678")
let resource = FeedlyCategoryResourceID(id: "user/1234/category/5678")
let newerThan: Date? = Date(timeIntervalSinceReferenceDate: 0)
let continuations = (1...10).map { "\($0)" }

View File

@@ -9,14 +9,14 @@
import XCTest
@testable import Account
final class TestGetPagedStreamIdsService: FeedlyGetStreamIdsService {
final class TestGetPagedStreamIdsService: FeedlyGetStreamIDsService {
var parameterTester: ((FeedlyResourceId, String?, Date?, Bool?) -> ())?
var getStreamIdsExpectation: XCTestExpectation?
var pages = [String: FeedlyStreamIds]()
var pages = [String: FeedlyStreamIDs]()
func addAtLeastOnePage(for resource: FeedlyResourceId, continuations: [String], numberOfEntriesPerPage count: Int) {
pages = [String: FeedlyStreamIds](minimumCapacity: continuations.count + 1)
pages = [String: FeedlyStreamIDs](minimumCapacity: continuations.count + 1)
// A continuation is an identifier for the next page.
// The first page has a nil identifier.
@@ -31,9 +31,9 @@ final class TestGetPagedStreamIdsService: FeedlyGetStreamIdsService {
}
}
private func makeStreamIds(for resource: FeedlyResourceId, continuation: String?, between range: Range<Int>) -> FeedlyStreamIds {
private func makeStreamIds(for resource: FeedlyResourceId, continuation: String?, between range: Range<Int>) -> FeedlyStreamIDs {
let entryIds = range.map { _ in UUID().uuidString }
let stream = FeedlyStreamIds(continuation: continuation, ids: entryIds)
let stream = FeedlyStreamIDs(continuation: continuation, ids: entryIds)
return stream
}
@@ -41,7 +41,7 @@ final class TestGetPagedStreamIdsService: FeedlyGetStreamIdsService {
return "\(stream.id)@\(continuation ?? "")"
}
func getStreamIds(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIds, Error>) -> ()) {
func getStreamIds(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIDs, Error>) -> ()) {
let key = TestGetPagedStreamIdsService.getPagingKey(for: resource, continuation: continuation)
guard let page = pages[key] else {
XCTFail("Missing page for \(resource.id) and continuation \(String(describing: continuation)). Test may time out because the completion will not be called.")

View File

@@ -9,13 +9,13 @@
import XCTest
@testable import Account
final class TestGetStreamIdsService: FeedlyGetStreamIdsService {
final class TestGetStreamIdsService: FeedlyGetStreamIDsService {
var mockResult: Result<FeedlyStreamIds, Error>?
var mockResult: Result<FeedlyStreamIDs, Error>?
var parameterTester: ((FeedlyResourceId, String?, Date?, Bool?) -> ())?
var getStreamIdsExpectation: XCTestExpectation?
func getStreamIds(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIds, Error>) -> ()) {
func getStreamIds(for resource: FeedlyResourceId, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIDs, Error>) -> ()) {
guard let result = mockResult else {
XCTFail("Missing mock result. Test may time out because the completion will not be called.")
return