Skip to content
This repository was archived by the owner on Jan 19, 2026. It is now read-only.

Commit 42c9517

Browse files
committed
Add post processing support for FileDownloadManager.
MessageDownloadManager now extracts source from json and proceeds saving
1 parent 4d3264a commit 42c9517

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

macOS/Services/FileDownloadManager.swift

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class FileDownloadTask: ObservableObject {
2626
let savedFileLocation: URL
2727
let fileName: String
2828
var error: Error?
29+
var beforeSave: ((URL) -> URL?)?
2930
var afterDownload: ((FileDownloadTask) -> Void)?
3031

3132
@Published var state: State = .idle
@@ -34,11 +35,13 @@ class FileDownloadTask: ObservableObject {
3435
task.progress
3536
}
3637

37-
init (task: URLSessionDownloadTask, fileName: String, savedFileLocation: URL, afterDownload: ((FileDownloadTask) -> Void)? = nil) {
38+
init (task: URLSessionDownloadTask, fileName: String, savedFileLocation: URL,
39+
beforeSave: ((URL) -> URL?)? = nil, afterDownload: ((FileDownloadTask) -> Void)? = nil) {
3840
self.task = task
3941
self.savedFileLocation = savedFileLocation
4042
self.fileName = fileName
4143
self.error = nil
44+
self.beforeSave = beforeSave
4245
self.afterDownload = afterDownload
4346
}
4447

@@ -65,15 +68,19 @@ final class FileDownloadManager: NSObject {
6568
}
6669

6770
func schedule(with request: URLRequest, fileName: String, saveLocation: URL? = nil,
68-
afterDownload: ((FileDownloadTask) -> Void)? = nil) -> FileDownloadTask {
71+
beforeSave: ((URL) -> URL?)? = nil, afterDownload: ((FileDownloadTask) -> Void)? = nil) -> FileDownloadTask {
6972
let downloadTask = session.downloadTask(with: request)
7073
let fileURL: URL
7174
if let saveLocation = saveLocation {
7275
fileURL = saveLocation
7376
} else {
7477
fileURL = Self.downloadDirectoryURL.appendingPathComponent(fileName)
7578
}
76-
let fileDownloadTask = FileDownloadTask(task: downloadTask, fileName: fileName, savedFileLocation: fileURL, afterDownload: afterDownload)
79+
let fileDownloadTask = FileDownloadTask(task: downloadTask,
80+
fileName: fileName,
81+
savedFileLocation: fileURL,
82+
beforeSave: beforeSave,
83+
afterDownload: afterDownload)
7784
tasks[fileDownloadTask.id] = fileDownloadTask
7885
return fileDownloadTask
7986
}
@@ -87,13 +94,16 @@ extension FileDownloadManager: URLSessionDownloadDelegate {
8794
return
8895
}
8996

90-
let desiredUrl = task.savedFileLocation
97+
let sourceFile = task.beforeSave?(location) ?? location
98+
99+
let savingLocation = task.savedFileLocation
100+
91101
do {
92-
let isFileExists = FileManager.default.fileExists(atPath: desiredUrl.path)
102+
let isFileExists = FileManager.default.fileExists(atPath: savingLocation.path)
93103
if isFileExists {
94-
_ = try FileManager.default.replaceItemAt(desiredUrl, withItemAt: location)
104+
_ = try FileManager.default.replaceItemAt(savingLocation, withItemAt: sourceFile)
95105
} else {
96-
try FileManager.default.moveItem(at: location, to: desiredUrl)
106+
try FileManager.default.moveItem(at: sourceFile, to: savingLocation)
97107
}
98108
task.state = .saved
99109
task.afterDownload?(task)

macOS/Services/MessageDownloadManager.swift

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import Resolver
1010
import MailTMSwift
1111

1212
class MessageDownloadManager {
13-
13+
1414
private var messageDownloadTasks: [Message.ID: FileDownloadTask] = [:]
1515

1616
private let fileDownloadManager: FileDownloadManager
1717

18+
private let decoder = JSONDecoder()
19+
1820
init(fileDownloadManger: FileDownloadManager = Resolver.resolve()) {
1921
self.fileDownloadManager = fileDownloadManger
2022
}
@@ -33,9 +35,40 @@ class MessageDownloadManager {
3335
} else {
3436
fileName = "\(message.data.subject).eml"
3537
}
36-
let task = fileDownloadManager.schedule(with: request, fileName: fileName, saveLocation: saveLocation, afterDownload: afterDownload)
38+
let task = fileDownloadManager.schedule(with: request, fileName: fileName, saveLocation: saveLocation,
39+
beforeSave: extractSource(location:), afterDownload: afterDownload)
3740
messageDownloadTasks[message.id] = task
3841
task.download()
3942
return task
4043
}
44+
45+
func extractSource(location: URL) -> URL? {
46+
guard FileManager.default.fileExists(atPath: location.path) else {
47+
return nil
48+
}
49+
50+
do {
51+
guard let data = try String(contentsOf: location).data(using: .utf8) else {
52+
return nil
53+
}
54+
let sourceObj = try decoder.decode(MTMessageSource.self, from: data)
55+
56+
let temporaryDirectoryURL =
57+
try FileManager.default.url(for: .itemReplacementDirectory,
58+
in: .userDomainMask,
59+
appropriateFor: location,
60+
create: true)
61+
62+
let temporaryFilename = UUID().uuidString
63+
64+
let temporaryFileURL =
65+
temporaryDirectoryURL.appendingPathComponent(temporaryFilename)
66+
67+
try sourceObj.data.write(to: temporaryFileURL, atomically: true, encoding: .utf8)
68+
return temporaryFileURL
69+
} catch {
70+
print(error)
71+
}
72+
return nil
73+
}
4174
}

0 commit comments

Comments
 (0)