Convert importOPML to async await.
This commit is contained in:
parent
887e35068e
commit
91b0e7158a
|
@ -428,28 +428,22 @@ public enum FetchType {
|
|||
try await delegate.syncArticleStatus(for: self)
|
||||
}
|
||||
|
||||
public func importOPML(_ opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
public func importOPML(_ opmlFile: URL) async throws {
|
||||
|
||||
guard !delegate.isOPMLImportInProgress else {
|
||||
completion(.failure(AccountError.opmlImportInProgress))
|
||||
return
|
||||
throw AccountError.opmlImportInProgress
|
||||
}
|
||||
|
||||
delegate.importOPML(for: self, opmlFile: opmlFile) { [weak self] result in
|
||||
switch result {
|
||||
case .success:
|
||||
guard let self = self else { return }
|
||||
// Reset the last fetch date to get the article history for the added feeds.
|
||||
self.metadata.lastArticleFetchStartTime = nil
|
||||
Task { @MainActor in
|
||||
try? await self.refreshAll()
|
||||
}
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
|
||||
try await delegate.importOPML(for: self, opmlFile: opmlFile)
|
||||
|
||||
// Reset the last fetch date to get the article history for the added feeds.
|
||||
metadata.lastArticleFetchStartTime = nil
|
||||
|
||||
Task { @MainActor in
|
||||
try? await self.refreshAll()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public func suspendNetwork() {
|
||||
delegate.suspendNetwork()
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import Secrets
|
|||
func sendArticleStatus(for account: Account) async throws
|
||||
func refreshArticleStatus(for account: Account) async throws
|
||||
|
||||
func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
func importOPML(for account:Account, opmlFile: URL) async throws
|
||||
|
||||
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void)
|
||||
func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result<Void, Error>) -> Void)
|
||||
|
|
|
@ -180,7 +180,21 @@ enum CloudKitAccountDelegateError: LocalizedError {
|
|||
}
|
||||
}
|
||||
|
||||
func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func importOPML(for account: Account, opmlFile: URL) async throws {
|
||||
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
self.importOPML(for: account, opmlFile: opmlFile) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
continuation.resume()
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard refreshProgress.isComplete else {
|
||||
completion(.success(()))
|
||||
return
|
||||
|
|
|
@ -279,7 +279,21 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
|
||||
}
|
||||
|
||||
func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func importOPML(for account: Account, opmlFile: URL) async throws {
|
||||
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
self.importOPML(for: account, opmlFile: opmlFile) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
continuation.resume()
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
var fileData: Data?
|
||||
|
||||
|
|
|
@ -255,7 +255,21 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
|||
operationQueue.addOperations([ingestUnread, ingestStarred])
|
||||
}
|
||||
|
||||
func importOPML(for account: Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func importOPML(for account: Account, opmlFile: URL) async throws {
|
||||
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
self.importOPML(for: account, opmlFile: opmlFile) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
continuation.resume()
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func importOPML(for account: Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
let data: Data
|
||||
|
||||
do {
|
||||
|
|
|
@ -67,50 +67,21 @@ final class LocalAccountDelegate: AccountDelegate {
|
|||
func refreshArticleStatus(for account: Account) async throws {
|
||||
}
|
||||
|
||||
func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func importOPML(for account:Account, opmlFile: URL) async throws {
|
||||
|
||||
Task { @MainActor in
|
||||
var fileData: Data?
|
||||
let opmlData = try Data(contentsOf: opmlFile)
|
||||
let parserData = ParserData(url: opmlFile.absoluteString, data: opmlData)
|
||||
|
||||
do {
|
||||
fileData = try Data(contentsOf: opmlFile)
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
return
|
||||
}
|
||||
let opmlDocument = try RSOPMLParser.parseOPML(with: parserData)
|
||||
guard let children = opmlDocument.children else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let opmlData = fileData else {
|
||||
completion(.success(()))
|
||||
return
|
||||
}
|
||||
|
||||
let parserData = ParserData(url: opmlFile.absoluteString, data: opmlData)
|
||||
var opmlDocument: RSOPMLDocument?
|
||||
|
||||
do {
|
||||
opmlDocument = try RSOPMLParser.parseOPML(with: parserData)
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
return
|
||||
}
|
||||
|
||||
guard let loadDocument = opmlDocument else {
|
||||
completion(.success(()))
|
||||
return
|
||||
}
|
||||
|
||||
guard let children = loadDocument.children else {
|
||||
return
|
||||
}
|
||||
|
||||
BatchUpdate.shared.perform {
|
||||
account.loadOPMLItems(children)
|
||||
}
|
||||
|
||||
completion(.success(()))
|
||||
BatchUpdate.shared.perform {
|
||||
account.loadOPMLItems(children)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func createFeed(for account: Account, url urlString: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result<Feed, Error>) -> Void) {
|
||||
guard let url = URL(string: urlString) else {
|
||||
completion(.failure(LocalAccountDelegateError.invalidParameter))
|
||||
|
|
|
@ -393,8 +393,7 @@ final class NewsBlurAccountDelegate: AccountDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
func importOPML(for account: Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> ()) {
|
||||
completion(.success(()))
|
||||
func importOPML(for account: Account, opmlFile: URL) async throws {
|
||||
}
|
||||
|
||||
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> ()) {
|
||||
|
|
|
@ -338,7 +338,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func importOPML(for account:Account, opmlFile: URL) async throws {
|
||||
}
|
||||
|
||||
func createFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
|
||||
|
|
|
@ -47,12 +47,12 @@ private extension NNW3ImportController {
|
|||
guard let opmlURL = convertToOPMLFile(subscriptionsPlistURL: subscriptionsPlistURL) else {
|
||||
return
|
||||
}
|
||||
account.importOPML(opmlURL) { result in
|
||||
try? FileManager.default.removeItem(at: opmlURL)
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
|
||||
Task { @MainActor in
|
||||
do {
|
||||
try await account.importOPML(opmlURL)
|
||||
try? FileManager.default.removeItem(at: opmlURL)
|
||||
} catch {
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import AppKit
|
|||
import Account
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
class ImportOPMLWindowController: NSWindowController {
|
||||
final class ImportOPMLWindowController: NSWindowController {
|
||||
|
||||
@IBOutlet weak var accountPopUpButton: NSPopUpButton!
|
||||
private weak var hostWindow: NSWindow?
|
||||
|
@ -90,18 +90,17 @@ class ImportOPMLWindowController: NSWindowController {
|
|||
panel.allowsOtherFileTypes = false
|
||||
|
||||
panel.beginSheetModal(for: hostWindow!) { modalResult in
|
||||
if modalResult == NSApplication.ModalResponse.OK, let url = panel.url {
|
||||
account.importOPML(url) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
guard modalResult == NSApplication.ModalResponse.OK, let url = panel.url else {
|
||||
return
|
||||
}
|
||||
|
||||
Task { @MainActor in
|
||||
do {
|
||||
try await account.importOPML(url)
|
||||
} catch {
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@ import Account
|
|||
@MainActor struct DefaultFeedsImporter {
|
||||
|
||||
static func importDefaultFeeds(account: Account) {
|
||||
let defaultFeedsURL = Bundle.main.url(forResource: "DefaultFeeds", withExtension: "opml")!
|
||||
AccountManager.shared.defaultAccount.importOPML(defaultFeedsURL) { result in }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let defaultFeedsURL = Bundle.main.url(forResource: "DefaultFeeds", withExtension: "opml")!
|
||||
|
||||
Task { @MainActor in
|
||||
try? await AccountManager.shared.defaultAccount.importOPML(defaultFeedsURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -349,12 +349,13 @@ class SettingsViewController: UITableViewController {
|
|||
extension SettingsViewController: UIDocumentPickerDelegate {
|
||||
|
||||
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
|
||||
|
||||
for url in urls {
|
||||
opmlAccount?.importOPML(url) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure:
|
||||
|
||||
Task { @MainActor in
|
||||
do {
|
||||
try await opmlAccount?.importOPML(url)
|
||||
} catch {
|
||||
let title = NSLocalizedString("Import Failed", comment: "Import Failed")
|
||||
let message = NSLocalizedString("We were unable to process the selected file. Please ensure that it is a properly formatted OPML file.", comment: "Import Failed Message")
|
||||
self.presentError(title: title, message: message)
|
||||
|
@ -362,7 +363,6 @@ extension SettingsViewController: UIDocumentPickerDelegate {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
|
Loading…
Reference in New Issue