Convert methods to async await.
This commit is contained in:
parent
a56ffa9405
commit
c2197ac854
@ -422,18 +422,9 @@ extension FeedlyAPICaller: FeedlyGetStreamContentsService {
|
|||||||
|
|
||||||
extension FeedlyAPICaller: FeedlyGetStreamIDsService {
|
extension FeedlyAPICaller: FeedlyGetStreamIDsService {
|
||||||
|
|
||||||
@MainActor func getStreamIDs(for resource: FeedlyResourceID, continuation: String? = nil, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIDs, Error>) -> ()) {
|
@MainActor func getStreamIDs(for resource: FeedlyResourceID, continuation: String? = nil, newerThan: Date?, unreadOnly: Bool?) async throws -> FeedlyStreamIDs {
|
||||||
guard !isSuspended else {
|
|
||||||
return DispatchQueue.main.async {
|
|
||||||
completion(.failure(TransportError.suspended))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let accessToken = credentials?.secret else {
|
guard !isSuspended else { throw TransportError.suspended }
|
||||||
return DispatchQueue.main.async {
|
|
||||||
completion(.failure(CredentialsError.incompleteCredentials))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var components = baseURLComponents
|
var components = baseURLComponents
|
||||||
components.path = "/v3/streams/ids"
|
components.path = "/v3/streams/ids"
|
||||||
@ -469,22 +460,16 @@ extension FeedlyAPICaller: FeedlyGetStreamIDsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var request = URLRequest(url: url)
|
var request = URLRequest(url: url)
|
||||||
request.addValue("application/json", forHTTPHeaderField: HTTPRequestHeader.contentType)
|
addJSONHeaders(&request)
|
||||||
request.addValue("application/json", forHTTPHeaderField: "Accept-Type")
|
try addOAuthAccessToken(&request)
|
||||||
request.addValue("OAuth \(accessToken)", forHTTPHeaderField: HTTPRequestHeader.authorization)
|
|
||||||
|
|
||||||
send(request: request, resultType: FeedlyStreamIDs.self, dateDecoding: .millisecondsSince1970, keyDecoding: .convertFromSnakeCase) { result in
|
let (_, collections) = try await send(request: request, resultType: FeedlyStreamIDs.self)
|
||||||
switch result {
|
|
||||||
case .success(let (_, collections)):
|
guard let collections else {
|
||||||
if let response = collections {
|
throw URLError(.cannotDecodeContentData)
|
||||||
completion(.success(response))
|
|
||||||
} else {
|
|
||||||
completion(.failure(URLError(.cannotDecodeContentData)))
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
completion(.failure(error))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return collections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,78 +45,44 @@ final class FeedlyIngestStarredArticleIDsOperation: FeedlyOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func getStreamIDs(_ continuation: String?) {
|
private func getStreamIDs(_ continuation: String?) {
|
||||||
service.getStreamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: nil, completion: didGetStreamIDs(_:))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func didGetStreamIDs(_ result: Result<FeedlyStreamIDs, Error>) {
|
Task { @MainActor in
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch result {
|
|
||||||
case .success(let streamIDs):
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
let streamIDs = try await service.getStreamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: nil)
|
||||||
remoteEntryIDs.formUnion(streamIDs.ids)
|
remoteEntryIDs.formUnion(streamIDs.ids)
|
||||||
|
|
||||||
guard let continuation = streamIDs.continuation else {
|
guard let continuation = streamIDs.continuation else {
|
||||||
removeEntryIDsWithPendingStatus()
|
try await removeEntryIDsWithPendingStatus()
|
||||||
|
didFinish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
getStreamIDs(continuation)
|
getStreamIDs(continuation)
|
||||||
|
|
||||||
case .failure(let error):
|
} catch {
|
||||||
didFinish(with: error)
|
didFinish(with: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 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.
|
/// 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() async throws {
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
if let pendingArticleIDs = try await database.selectPendingStarredStatusArticleIDs() {
|
||||||
return
|
remoteEntryIDs.subtract(pendingArticleIDs)
|
||||||
|
}
|
||||||
|
try await updateStarredStatuses()
|
||||||
}
|
}
|
||||||
|
|
||||||
Task { @MainActor in
|
private func updateStarredStatuses() async throws {
|
||||||
|
|
||||||
do {
|
|
||||||
if let pendingArticleIDs = try await self.database.selectPendingStarredStatusArticleIDs() {
|
|
||||||
self.remoteEntryIDs.subtract(pendingArticleIDs)
|
|
||||||
}
|
|
||||||
self.updateStarredStatuses()
|
|
||||||
} catch {
|
|
||||||
self.didFinish(with: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func updateStarredStatuses() {
|
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Task { @MainActor in
|
|
||||||
|
|
||||||
do {
|
|
||||||
if let localStarredArticleIDs = try await account.fetchStarredArticleIDs() {
|
if let localStarredArticleIDs = try await account.fetchStarredArticleIDs() {
|
||||||
self.processStarredArticleIDs(localStarredArticleIDs)
|
try await processStarredArticleIDs(localStarredArticleIDs)
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
self.didFinish(with: error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func processStarredArticleIDs(_ localStarredArticleIDs: Set<String>) {
|
func processStarredArticleIDs(_ localStarredArticleIDs: Set<String>) async throws {
|
||||||
|
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Task { @MainActor in
|
|
||||||
|
|
||||||
var markAsStarredError: Error?
|
var markAsStarredError: Error?
|
||||||
var markAsUnstarredError: Error?
|
var markAsUnstarredError: Error?
|
||||||
@ -136,10 +102,7 @@ final class FeedlyIngestStarredArticleIDsOperation: FeedlyOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let markingError = markAsStarredError ?? markAsUnstarredError {
|
if let markingError = markAsStarredError ?? markAsUnstarredError {
|
||||||
self.didFinish(with: markingError)
|
throw markingError
|
||||||
}
|
|
||||||
|
|
||||||
self.didFinish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,20 +41,12 @@ class FeedlyIngestStreamArticleIDsOperation: FeedlyOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func getStreamIDs(_ continuation: String?) {
|
private func getStreamIDs(_ continuation: String?) {
|
||||||
service.getStreamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: nil, completion: didGetStreamIDs(_:))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func didGetStreamIDs(_ result: Result<FeedlyStreamIDs, Error>) {
|
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch result {
|
|
||||||
case .success(let streamIDs):
|
|
||||||
|
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
let streamIDs = try await service.getStreamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: nil)
|
||||||
|
|
||||||
try await account.createStatusesIfNeeded(articleIDs: Set(streamIDs.ids))
|
try await account.createStatusesIfNeeded(articleIDs: Set(streamIDs.ids))
|
||||||
|
|
||||||
guard let continuation = streamIDs.continuation else {
|
guard let continuation = streamIDs.continuation else {
|
||||||
@ -62,15 +54,11 @@ class FeedlyIngestStreamArticleIDsOperation: FeedlyOperation {
|
|||||||
self.didFinish()
|
self.didFinish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.getStreamIDs(continuation)
|
self.getStreamIDs(continuation)
|
||||||
|
|
||||||
} catch {
|
} catch {
|
||||||
self.didFinish(with: error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
didFinish(with: error)
|
didFinish(with: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,81 +46,47 @@ final class FeedlyIngestUnreadArticleIDsOperation: FeedlyOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func getStreamIDs(_ continuation: String?) {
|
private func getStreamIDs(_ continuation: String?) {
|
||||||
service.getStreamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: true, completion: didGetStreamIDs(_:))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func didGetStreamIDs(_ result: Result<FeedlyStreamIDs, Error>) {
|
Task { @MainActor in
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch result {
|
|
||||||
case .success(let streamIDs):
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
let streamIDs = try await service.getStreamIDs(for: resource, continuation: continuation, newerThan: nil, unreadOnly: true)
|
||||||
remoteEntryIDs.formUnion(streamIDs.ids)
|
remoteEntryIDs.formUnion(streamIDs.ids)
|
||||||
|
|
||||||
guard let continuation = streamIDs.continuation else {
|
guard let continuation = streamIDs.continuation else {
|
||||||
removeEntryIDsWithPendingStatus()
|
try await removeEntryIDsWithPendingStatus()
|
||||||
|
didFinish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
getStreamIDs(continuation)
|
getStreamIDs(continuation)
|
||||||
|
|
||||||
case .failure(let error):
|
} catch {
|
||||||
didFinish(with: error)
|
didFinish(with: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 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.
|
/// 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() async throws {
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
if let pendingArticleIDs = try await database.selectPendingReadStatusArticleIDs() {
|
||||||
return
|
remoteEntryIDs.subtract(pendingArticleIDs)
|
||||||
|
}
|
||||||
|
try await updateUnreadStatuses()
|
||||||
}
|
}
|
||||||
|
|
||||||
Task { @MainActor in
|
private func updateUnreadStatuses() async throws {
|
||||||
|
|
||||||
do {
|
|
||||||
if let pendingArticleIDs = try await self.database.selectPendingReadStatusArticleIDs() {
|
|
||||||
self.remoteEntryIDs.subtract(pendingArticleIDs)
|
|
||||||
}
|
|
||||||
self.updateUnreadStatuses()
|
|
||||||
} catch {
|
|
||||||
self.didFinish(with: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func updateUnreadStatuses() {
|
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Task { @MainActor in
|
|
||||||
|
|
||||||
do {
|
|
||||||
if let localUnreadArticleIDs = try await account.fetchUnreadArticleIDs() {
|
if let localUnreadArticleIDs = try await account.fetchUnreadArticleIDs() {
|
||||||
self.processUnreadArticleIDs(localUnreadArticleIDs)
|
try await processUnreadArticleIDs(localUnreadArticleIDs)
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
self.didFinish(with: error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func processUnreadArticleIDs(_ localUnreadArticleIDs: Set<String>) {
|
private func processUnreadArticleIDs(_ localUnreadArticleIDs: Set<String>) async throws {
|
||||||
|
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let remoteUnreadArticleIDs = remoteEntryIDs
|
let remoteUnreadArticleIDs = remoteEntryIDs
|
||||||
|
|
||||||
Task { @MainActor in
|
|
||||||
|
|
||||||
var markAsUnreadError: Error?
|
var markAsUnreadError: Error?
|
||||||
var markAsReadError: Error?
|
var markAsReadError: Error?
|
||||||
|
|
||||||
@ -138,10 +104,7 @@ final class FeedlyIngestUnreadArticleIDsOperation: FeedlyOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let markingError = markAsReadError ?? markAsUnreadError {
|
if let markingError = markAsReadError ?? markAsUnreadError {
|
||||||
self.didFinish(with: markingError)
|
throw markingError
|
||||||
}
|
|
||||||
|
|
||||||
self.didFinish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import Foundation
|
|||||||
import os.log
|
import os.log
|
||||||
|
|
||||||
public protocol FeedlyGetStreamIDsOperationDelegate: AnyObject {
|
public protocol FeedlyGetStreamIDsOperationDelegate: AnyObject {
|
||||||
|
|
||||||
func feedlyGetStreamIDsOperation(_ operation: FeedlyGetStreamIDsOperation, didGet streamIDs: FeedlyStreamIDs)
|
func feedlyGetStreamIDsOperation(_ operation: FeedlyGetStreamIDsOperation, didGet streamIDs: FeedlyStreamIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,16 +47,15 @@ public final class FeedlyGetStreamIDsOperation: FeedlyOperation, FeedlyEntryIden
|
|||||||
weak var streamIDsDelegate: FeedlyGetStreamIDsOperationDelegate?
|
weak var streamIDsDelegate: FeedlyGetStreamIDsOperationDelegate?
|
||||||
|
|
||||||
public override func run() {
|
public override func run() {
|
||||||
service.getStreamIDs(for: resource, continuation: continuation, newerThan: newerThan, unreadOnly: unreadOnly) { result in
|
|
||||||
switch result {
|
Task { @MainActor in
|
||||||
case .success(let stream):
|
|
||||||
|
do {
|
||||||
|
let stream = try await service.getStreamIDs(for: resource, continuation: continuation, newerThan: newerThan, unreadOnly: unreadOnly)
|
||||||
self.streamIDs = stream
|
self.streamIDs = stream
|
||||||
|
|
||||||
self.streamIDsDelegate?.feedlyGetStreamIDsOperation(self, didGet: stream)
|
self.streamIDsDelegate?.feedlyGetStreamIDsOperation(self, didGet: stream)
|
||||||
|
|
||||||
self.didFinish()
|
self.didFinish()
|
||||||
|
} catch {
|
||||||
case .failure(let error):
|
|
||||||
os_log(.debug, log: self.log, "Unable to get stream ids: %{public}@.", error as NSError)
|
os_log(.debug, log: self.log, "Unable to get stream ids: %{public}@.", error as NSError)
|
||||||
self.didFinish(with: error)
|
self.didFinish(with: error)
|
||||||
}
|
}
|
||||||
|
@ -45,25 +45,18 @@ public final class FeedlyGetUpdatedArticleIDsOperation: FeedlyOperation, FeedlyE
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func getStreamIDs(_ continuation: String?) {
|
private func getStreamIDs(_ continuation: String?) {
|
||||||
|
|
||||||
|
Task { @MainActor in
|
||||||
guard let date = newerThan else {
|
guard let date = newerThan else {
|
||||||
os_log(.debug, log: log, "No date provided so everything must be new (nothing is updated).")
|
os_log(.debug, log: log, "No date provided so everything must be new (nothing is updated).")
|
||||||
didFinish()
|
didFinish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
service.getStreamIDs(for: resource, continuation: continuation, newerThan: date, unreadOnly: nil, completion: didGetStreamIDs(_:))
|
do {
|
||||||
}
|
let streamIDs = try await service.getStreamIDs(for: resource, continuation: continuation, newerThan: date, unreadOnly: nil)
|
||||||
|
|
||||||
private func didGetStreamIDs(_ result: Result<FeedlyStreamIDs, Error>) {
|
|
||||||
guard !isCanceled else {
|
|
||||||
didFinish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch result {
|
|
||||||
case .success(let streamIDs):
|
|
||||||
storedUpdatedArticleIDs.formUnion(streamIDs.ids)
|
storedUpdatedArticleIDs.formUnion(streamIDs.ids)
|
||||||
|
|
||||||
guard let continuation = streamIDs.continuation else {
|
guard let continuation = streamIDs.continuation else {
|
||||||
os_log(.debug, log: log, "%{public}i articles updated since last successful sync start date.", storedUpdatedArticleIDs.count)
|
os_log(.debug, log: log, "%{public}i articles updated since last successful sync start date.", storedUpdatedArticleIDs.count)
|
||||||
didFinish()
|
didFinish()
|
||||||
@ -72,8 +65,9 @@ public final class FeedlyGetUpdatedArticleIDsOperation: FeedlyOperation, FeedlyE
|
|||||||
|
|
||||||
getStreamIDs(continuation)
|
getStreamIDs(continuation)
|
||||||
|
|
||||||
case .failure(let error):
|
} catch {
|
||||||
didFinish(with: error)
|
didFinish(with: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol FeedlyGetStreamIDsService: AnyObject {
|
public protocol FeedlyGetStreamIDsService: AnyObject {
|
||||||
func getStreamIDs(for resource: FeedlyResourceID, continuation: String?, newerThan: Date?, unreadOnly: Bool?, completion: @escaping (Result<FeedlyStreamIDs, Error>) -> ())
|
|
||||||
|
@MainActor func getStreamIDs(for resource: FeedlyResourceID, continuation: String?, newerThan: Date?, unreadOnly: Bool?) async throws -> FeedlyStreamIDs
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user