Skip to content

Commit 216a7eb

Browse files
committed
Prevent system from deleting caches while app is running
1 parent 9f1173a commit 216a7eb

File tree

4 files changed

+48
-36
lines changed

4 files changed

+48
-36
lines changed

Mixin/Service/DeviceTransfer/DeviceTransferClient.swift

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ final class DeviceTransferClient {
2121
private let key: DeviceTransferKey
2222
private let remotePlatform: DeviceTransferPlatform
2323
private let connection: NWConnection
24+
private let cacheContainerURL: URL
25+
private let messageProcessor: DeviceTransferMessageProcessor
2426
private let queue = Queue(label: "one.mixin.messenger.DeviceTransferClient")
25-
private let cacheContainerURL = FileManager.default.temporaryDirectory.appendingPathComponent("DeviceTransfer", isDirectory: true)
2627
private let speedInspector = NetworkSpeedInspector()
27-
private let messageProcessor: DeviceTransferMessageProcessor
2828

2929
private weak var statisticsTimer: Timer?
3030

@@ -40,7 +40,18 @@ final class DeviceTransferClient {
4040
Unmanaged<DeviceTransferClient>.passUnretained(self).toOpaque()
4141
}
4242

43-
init(hostname: String, port: UInt16, code: UInt16, key: DeviceTransferKey, remotePlatform: DeviceTransferPlatform) {
43+
init(hostname: String, port: UInt16, code: UInt16, key: DeviceTransferKey, remotePlatform: DeviceTransferPlatform) throws {
44+
// https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW2
45+
// In iOS 5.0 and later, the system may delete the Caches directory on rare occasions when the system is very low on disk space.
46+
// This will never occur while an app is running.
47+
let manager = FileManager.default
48+
let cacheContainerURL = try manager.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
49+
.appendingPathComponent("DeviceTransfer")
50+
if manager.fileExists(atPath: cacheContainerURL.path) {
51+
try? manager.removeItem(at: cacheContainerURL)
52+
}
53+
try manager.createDirectory(at: cacheContainerURL, withIntermediateDirectories: true)
54+
4455
self.hostname = hostname
4556
self.port = port
4657
self.code = code
@@ -52,6 +63,7 @@ final class DeviceTransferClient {
5263
let endpoint = NWEndpoint.hostPort(host: host, port: port)
5364
return NWConnection(to: endpoint, using: .deviceTransfer)
5465
}()
66+
self.cacheContainerURL = cacheContainerURL
5567
self.messageProcessor = .init(key: key.aes,
5668
remotePlatform: remotePlatform,
5769
cacheContainerURL: cacheContainerURL,
@@ -65,17 +77,6 @@ final class DeviceTransferClient {
6577

6678
func start() {
6779
Logger.general.info(category: "DeviceTransferClient", message: "Will start connecting to [\(hostname)]:\(port)")
68-
do {
69-
let manager = FileManager.default
70-
if manager.fileExists(atPath: cacheContainerURL.path) {
71-
try? manager.removeItem(at: cacheContainerURL)
72-
}
73-
try manager.createDirectory(at: cacheContainerURL, withIntermediateDirectories: true)
74-
} catch {
75-
Logger.general.error(category: "DeviceTransferClient", message: "Failed to create cache container: \(error)")
76-
fail(error: .createCacheContainer(error))
77-
return
78-
}
7980
messageProcessor.$processingError
8081
.receive(on: queue.dispatchQueue)
8182
.sink { error in

Mixin/Service/DeviceTransfer/DeviceTransferError.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ enum DeviceTransferError: Error {
77
case mismatchedHMAC(local: Data, remote: Data)
88
case connectionFailed(Error)
99
case receiveFile(Error)
10-
case createCacheContainer(Error)
1110
case importing(DeviceTransferMessageProcessor.ProcessingError)
1211
}

Mixin/UserInterface/Controllers/DeviceTransfer/RestoreFromDesktopViewController.swift

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,24 @@ extension RestoreFromDesktopViewController {
119119
dataSource.replaceSection(at: 0, with: section, animation: .automatic)
120120
tableView.isUserInteractionEnabled = true
121121
case let .push(context):
122-
let client = DeviceTransferClient(hostname: context.hostname,
123-
port: context.port,
124-
code: context.code,
125-
key: context.key,
126-
remotePlatform: command.platform)
127-
stateObserver = client.$state
128-
.receive(on: DispatchQueue.main)
129-
.sink { [weak self] state in
130-
self?.stateDidChange(client: client, state: state)
122+
do {
123+
let client = try DeviceTransferClient(hostname: context.hostname,
124+
port: context.port,
125+
code: context.code,
126+
key: context.key,
127+
remotePlatform: command.platform)
128+
stateObserver = client.$state
129+
.receive(on: DispatchQueue.main)
130+
.sink { [weak self] state in
131+
self?.stateDidChange(client: client, state: state)
132+
}
133+
client.start()
134+
} catch {
135+
Logger.general.error(category: "RestoreFromDesktop", message: "Unable to init client: \(error)")
136+
alert(R.string.localizable.connection_establishment_failed(), message: nil) { _ in
137+
self.navigationController?.popViewController(animated: true)
131138
}
132-
client.start()
139+
}
133140
default:
134141
Logger.general.info(category: "RestoreFromDesktop", message: "Invalid command")
135142
alert(R.string.localizable.connection_establishment_failed(), message: nil) { _ in

Mixin/UserInterface/Windows/UrlWindow.swift

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -888,17 +888,22 @@ class UrlWindow {
888888
UIApplication.currentActivity()?.alert(R.string.localizable.unable_synced_between_different_account())
889889
return true
890890
}
891-
let client = DeviceTransferClient(hostname: context.hostname,
892-
port: context.port,
893-
code: context.code,
894-
key: context.key,
895-
remotePlatform: command.platform)
896-
client.start()
897-
let progress = DeviceTransferProgressViewController(connection: .client(client, .phone))
898-
if let navigationController = AppDelegate.current.mainWindow.rootViewController as? UINavigationController {
899-
navigationController.pushViewController(progress, animated: true)
900-
} else {
901-
AppDelegate.current.mainWindow.rootViewController?.present(progress, animated: true)
891+
do {
892+
let client = try DeviceTransferClient(hostname: context.hostname,
893+
port: context.port,
894+
code: context.code,
895+
key: context.key,
896+
remotePlatform: command.platform)
897+
client.start()
898+
let progress = DeviceTransferProgressViewController(connection: .client(client, .phone))
899+
if let navigationController = AppDelegate.current.mainWindow.rootViewController as? UINavigationController {
900+
navigationController.pushViewController(progress, animated: true)
901+
} else {
902+
AppDelegate.current.mainWindow.rootViewController?.present(progress, animated: true)
903+
}
904+
} catch {
905+
Logger.general.error(category: "UrlWindow", message: "Unable to init client: \(error)")
906+
UIApplication.currentActivity()?.alert(R.string.localizable.connection_establishment_failed())
902907
}
903908
return true
904909
}

0 commit comments

Comments
 (0)