Make ArticleThemeDownloader a struct with static funcs, which fixes the concurrency warning about the static shared property (which got removed).
This commit is contained in:
parent
8ad09228db
commit
cda4c9eb29
@ -338,7 +338,7 @@ import Sparkle
|
|||||||
shuttingDown = true
|
shuttingDown = true
|
||||||
saveState()
|
saveState()
|
||||||
|
|
||||||
ArticleThemeDownloader.shared.cleanUp()
|
ArticleThemeDownloader.cleanUp()
|
||||||
|
|
||||||
accountManager.sendArticleStatusAll() {
|
accountManager.sendArticleStatusAll() {
|
||||||
self.isShutDownSyncDone = true
|
self.isShutDownSyncDone = true
|
||||||
|
@ -62,7 +62,7 @@ extension AppDelegate : AppDelegateAppleEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try ArticleThemeDownloader.shared.handleFile(at: location)
|
try ArticleThemeDownloader.handleFile(at: location)
|
||||||
} catch {
|
} catch {
|
||||||
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error": error])
|
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error": error])
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Zip
|
import Zip
|
||||||
|
|
||||||
public class ArticleThemeDownloader {
|
struct ArticleThemeDownloader {
|
||||||
|
|
||||||
public enum ArticleThemeDownloaderError: LocalizedError {
|
public enum ArticleThemeDownloaderError: LocalizedError {
|
||||||
case noThemeFile
|
case noThemeFile
|
||||||
@ -22,26 +22,41 @@ public class ArticleThemeDownloader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static let shared = ArticleThemeDownloader()
|
static func handleFile(at location: URL) throws {
|
||||||
private init() {}
|
|
||||||
|
|
||||||
public func handleFile(at location: URL) throws {
|
|
||||||
createDownloadDirectoryIfRequired()
|
createDownloadDirectoryIfRequired()
|
||||||
let movedFileLocation = try moveTheme(from: location)
|
let movedFileLocation = try moveTheme(from: location)
|
||||||
let unzippedFileLocation = try unzipFile(at: movedFileLocation)
|
let unzippedFileLocation = try unzipFile(at: movedFileLocation)
|
||||||
NotificationCenter.default.post(name: .didEndDownloadingTheme, object: nil, userInfo: ["url" : unzippedFileLocation])
|
NotificationCenter.default.post(name: .didEndDownloadingTheme, object: nil, userInfo: ["url" : unzippedFileLocation])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes downloaded themes, where themes == folders, from `Application Support/NetNewsWire/Downloads`.
|
||||||
|
static func cleanUp() {
|
||||||
|
guard let filenames = try? FileManager.default.contentsOfDirectory(atPath: downloadDirectory().path) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for path in filenames {
|
||||||
|
do {
|
||||||
|
if FileManager.default.isFolder(atPath: downloadDirectory().appendingPathComponent(path).path) {
|
||||||
|
try FileManager.default.removeItem(atPath: downloadDirectory().appendingPathComponent(path).path)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension ArticleThemeDownloader {
|
||||||
|
|
||||||
/// Creates `Application Support/NetNewsWire/Downloads` if needed.
|
/// Creates `Application Support/NetNewsWire/Downloads` if needed.
|
||||||
private func createDownloadDirectoryIfRequired() {
|
static func createDownloadDirectoryIfRequired() {
|
||||||
try? FileManager.default.createDirectory(at: downloadDirectory(), withIntermediateDirectories: true, attributes: nil)
|
try? FileManager.default.createDirectory(at: downloadDirectory(), withIntermediateDirectories: true, attributes: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves the downloaded `.tmp` file to the `downloadDirectory` and renames it a `.zip`
|
/// Moves the downloaded `.tmp` file to the `downloadDirectory` and renames it a `.zip`
|
||||||
/// - Parameter location: The temporary file location.
|
/// - Parameter location: The temporary file location.
|
||||||
/// - Returns: Destination `URL`.
|
/// - Returns: Destination `URL`.
|
||||||
private func moveTheme(from location: URL) throws -> URL {
|
static func moveTheme(from location: URL) throws -> URL {
|
||||||
var tmpFileName = location.lastPathComponent
|
var tmpFileName = location.lastPathComponent
|
||||||
tmpFileName = tmpFileName.replacingOccurrences(of: ".tmp", with: ".zip")
|
tmpFileName = tmpFileName.replacingOccurrences(of: ".tmp", with: ".zip")
|
||||||
let fileUrl = downloadDirectory().appendingPathComponent("\(tmpFileName)")
|
let fileUrl = downloadDirectory().appendingPathComponent("\(tmpFileName)")
|
||||||
@ -52,7 +67,7 @@ public class ArticleThemeDownloader {
|
|||||||
/// Unzips the zip file
|
/// Unzips the zip file
|
||||||
/// - Parameter location: Location of the zip archive.
|
/// - Parameter location: Location of the zip archive.
|
||||||
/// - Returns: Enclosed `.nnwtheme` file.
|
/// - Returns: Enclosed `.nnwtheme` file.
|
||||||
private func unzipFile(at location: URL) throws -> URL {
|
static func unzipFile(at location: URL) throws -> URL {
|
||||||
do {
|
do {
|
||||||
let unzipDirectory = URL(fileURLWithPath: location.path.replacingOccurrences(of: ".zip", with: ""))
|
let unzipDirectory = URL(fileURLWithPath: location.path.replacingOccurrences(of: ".zip", with: ""))
|
||||||
try Zip.unzipFile(location, destination: unzipDirectory, overwrite: true, password: nil, progress: nil, fileOutputHandler: nil) // Unzips to folder in Application Support/NetNewsWire/Downloads
|
try Zip.unzipFile(location, destination: unzipDirectory, overwrite: true, password: nil, progress: nil, fileOutputHandler: nil) // Unzips to folder in Application Support/NetNewsWire/Downloads
|
||||||
@ -68,11 +83,10 @@ public class ArticleThemeDownloader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Performs a deep search of the unzipped directory to find the theme file.
|
/// Performs a deep search of the unzipped directory to find the theme file.
|
||||||
/// - Parameter searchPath: directory to search
|
/// - Parameter searchPath: directory to search
|
||||||
/// - Returns: optional `String`
|
/// - Returns: optional `String`
|
||||||
private func findThemeFile(in searchPath: String) -> String? {
|
static func findThemeFile(in searchPath: String) -> String? {
|
||||||
if let directoryContents = FileManager.default.enumerator(atPath: searchPath) {
|
if let directoryContents = FileManager.default.enumerator(atPath: searchPath) {
|
||||||
while let file = directoryContents.nextObject() as? String {
|
while let file = directoryContents.nextObject() as? String {
|
||||||
if file.hasSuffix(".nnwtheme") {
|
if file.hasSuffix(".nnwtheme") {
|
||||||
@ -86,23 +100,7 @@ public class ArticleThemeDownloader {
|
|||||||
|
|
||||||
/// The download directory used by the theme downloader: `Application Support/NetNewsWire/Downloads`
|
/// The download directory used by the theme downloader: `Application Support/NetNewsWire/Downloads`
|
||||||
/// - Returns: `URL`
|
/// - Returns: `URL`
|
||||||
private func downloadDirectory() -> URL {
|
static func downloadDirectory() -> URL {
|
||||||
FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!.appendingPathComponent("NetNewsWire/Downloads", isDirectory: true)
|
FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!.appendingPathComponent("NetNewsWire/Downloads", isDirectory: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes downloaded themes, where themes == folders, from `Application Support/NetNewsWire/Downloads`.
|
|
||||||
public func cleanUp() {
|
|
||||||
guard let filenames = try? FileManager.default.contentsOfDirectory(atPath: downloadDirectory().path) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for path in filenames {
|
|
||||||
do {
|
|
||||||
if FileManager.default.isFolder(atPath: downloadDirectory().appendingPathComponent(path).path) {
|
|
||||||
try FileManager.default.removeItem(atPath: downloadDirectory().appendingPathComponent(path).path)
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
print(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ private extension AppDelegate {
|
|||||||
|
|
||||||
accountManager.suspendNetworkAll()
|
accountManager.suspendNetworkAll()
|
||||||
accountManager.suspendDatabaseAll()
|
accountManager.suspendDatabaseAll()
|
||||||
ArticleThemeDownloader.shared.cleanUp()
|
ArticleThemeDownloader.cleanUp()
|
||||||
|
|
||||||
CoalescingQueue.standard.performCallsImmediately()
|
CoalescingQueue.standard.performCallsImmediately()
|
||||||
for scene in UIApplication.shared.connectedScenes {
|
for scene in UIApplication.shared.connectedScenes {
|
||||||
|
@ -192,7 +192,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
let location = location else { return }
|
let location = location else { return }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try ArticleThemeDownloader.shared.handleFile(at: location)
|
try ArticleThemeDownloader.handleFile(at: location)
|
||||||
} catch {
|
} catch {
|
||||||
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error": error])
|
NotificationCenter.default.post(name: .didFailToImportThemeWithError, object: nil, userInfo: ["error": error])
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user