Convert importOPML to async await.
This commit is contained in:
parent
6b1e41b694
commit
d912bcbe79
@ -48,10 +48,10 @@ let package = Package(
|
|||||||
"FeedFinder",
|
"FeedFinder",
|
||||||
"CommonErrors",
|
"CommonErrors",
|
||||||
"Feedly"
|
"Feedly"
|
||||||
|
],
|
||||||
|
swiftSettings: [
|
||||||
|
.enableExperimentalFeature("StrictConcurrency")
|
||||||
]
|
]
|
||||||
// swiftSettings: [
|
|
||||||
// .enableExperimentalFeature("StrictConcurrency")
|
|
||||||
// ]
|
|
||||||
),
|
),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "AccountTests",
|
name: "AccountTests",
|
||||||
|
@ -259,56 +259,27 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
|||||||
|
|
||||||
func importOPML(for account: Account, opmlFile: URL) async throws {
|
func importOPML(for account: Account, opmlFile: URL) async throws {
|
||||||
|
|
||||||
try await withCheckedThrowingContinuation { continuation in
|
let data = try Data(contentsOf: opmlFile)
|
||||||
self.importOPML(for: account, opmlFile: opmlFile) { result in
|
|
||||||
switch result {
|
os_log(.debug, log: log, "Begin importing OPML…")
|
||||||
case .success:
|
|
||||||
continuation.resume()
|
|
||||||
case .failure(let error):
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func importOPML(for account: Account, opmlFile: URL, completion: @escaping @Sendable (Result<Void, Error>) -> Void) {
|
|
||||||
let data: Data
|
|
||||||
|
|
||||||
do {
|
|
||||||
data = try Data(contentsOf: opmlFile)
|
|
||||||
} catch {
|
|
||||||
completion(.failure(error))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
os_log(.debug, log: log, "Begin importing OPML...")
|
|
||||||
isOPMLImportInProgress = true
|
isOPMLImportInProgress = true
|
||||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
refreshProgress.addTask()
|
||||||
|
defer {
|
||||||
caller.importOpml(data) { result in
|
isOPMLImportInProgress = false
|
||||||
|
refreshProgress.completeTask()
|
||||||
|
}
|
||||||
|
|
||||||
MainActor.assumeIsolated {
|
do {
|
||||||
switch result {
|
try await caller.importOPML(data)
|
||||||
case .success:
|
os_log(.debug, log: self.log, "Import OPML done.")
|
||||||
os_log(.debug, log: self.log, "Import OPML done.")
|
} catch {
|
||||||
self.refreshProgress.completeTask()
|
os_log(.debug, log: self.log, "Import OPML failed.")
|
||||||
self.isOPMLImportInProgress = false
|
let wrappedError = AccountError.wrappedError(error: error, account: account)
|
||||||
DispatchQueue.main.async {
|
throw wrappedError
|
||||||
completion(.success(()))
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
os_log(.debug, log: self.log, "Import OPML failed.")
|
|
||||||
self.refreshProgress.completeTask()
|
|
||||||
self.isOPMLImportInProgress = false
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
let wrappedError = AccountError.wrappedError(error: error, account: account)
|
|
||||||
completion(.failure(wrappedError))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFolder(for account: Account, name: String) async throws -> Folder {
|
func createFolder(for account: Account, name: String) async throws -> Folder {
|
||||||
|
|
||||||
try await withCheckedThrowingContinuation { continuation in
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
|
@ -17,8 +17,8 @@ protocol FeedlyAPICallerDelegate: AnyObject {
|
|||||||
@MainActor func reauthorizeFeedlyAPICaller(_ caller: FeedlyAPICaller, completionHandler: @escaping (Bool) -> ())
|
@MainActor func reauthorizeFeedlyAPICaller(_ caller: FeedlyAPICaller, completionHandler: @escaping (Bool) -> ())
|
||||||
}
|
}
|
||||||
|
|
||||||
final class FeedlyAPICaller {
|
@MainActor final class FeedlyAPICaller {
|
||||||
|
|
||||||
enum API {
|
enum API {
|
||||||
case sandbox
|
case sandbox
|
||||||
case cloud
|
case cloud
|
||||||
@ -151,43 +151,32 @@ final class FeedlyAPICaller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func importOpml(_ opmlData: Data, completion: @escaping @Sendable (Result<Void, Error>) -> ()) {
|
func importOPML(_ opmlData: Data) async throws {
|
||||||
|
|
||||||
guard !isSuspended else {
|
guard !isSuspended else {
|
||||||
return DispatchQueue.main.async {
|
throw TransportError.suspended
|
||||||
completion(.failure(TransportError.suspended))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let accessToken = credentials?.secret else {
|
guard let accessToken = credentials?.secret else {
|
||||||
return DispatchQueue.main.async {
|
throw CredentialsError.incompleteCredentials
|
||||||
completion(.failure(CredentialsError.incompleteCredentials))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var components = baseUrlComponents
|
var components = baseUrlComponents
|
||||||
components.path = "/v3/opml"
|
components.path = "/v3/opml"
|
||||||
|
|
||||||
guard let url = components.url else {
|
guard let url = components.url else {
|
||||||
fatalError("\(components) does not produce a valid URL.")
|
fatalError("\(components) does not produce a valid URL.")
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = URLRequest(url: url)
|
var request = URLRequest(url: url)
|
||||||
request.httpMethod = "POST"
|
request.httpMethod = "POST"
|
||||||
request.addValue("text/xml", forHTTPHeaderField: HTTPRequestHeader.contentType)
|
request.addValue("text/xml", forHTTPHeaderField: HTTPRequestHeader.contentType)
|
||||||
request.addValue("application/json", forHTTPHeaderField: "Accept-Type")
|
request.addValue("application/json", forHTTPHeaderField: "Accept-Type")
|
||||||
request.addValue("OAuth \(accessToken)", forHTTPHeaderField: HTTPRequestHeader.authorization)
|
request.addValue("OAuth \(accessToken)", forHTTPHeaderField: HTTPRequestHeader.authorization)
|
||||||
request.httpBody = opmlData
|
request.httpBody = opmlData
|
||||||
|
|
||||||
send(request: request, resultType: String.self, dateDecoding: .millisecondsSince1970, keyDecoding: .convertFromSnakeCase) { result in
|
let (httpResponse, _) = try await send(request: request, resultType: String.self)
|
||||||
switch result {
|
if httpResponse.statusCode != HTTPResponseCode.OK {
|
||||||
case .success(let (httpResponse, _)):
|
throw URLError(.cannotDecodeContentData)
|
||||||
if httpResponse.statusCode == 200 {
|
|
||||||
completion(.success(()))
|
|
||||||
} else {
|
|
||||||
completion(.failure(URLError(.cannotDecodeContentData)))
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
completion(.failure(error))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user