session-ios/Signal/src/util/OWSBackupLazyRestoreJob.swift
2018-04-13 14:59:38 -04:00

93 lines
3.3 KiB
Swift

//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Foundation
import PromiseKit
import SignalServiceKit
@objc
public class OWSBackupLazyRestoreJob: NSObject {
let primaryStorage: OWSPrimaryStorage
private var jobTempDirPath: String?
deinit {
if let jobTempDirPath = self.jobTempDirPath {
DispatchQueue.global().async {
OWSFileSystem.deleteFile(jobTempDirPath)
}
}
}
@objc
public class func runAsync() {
OWSBackupLazyRestoreJob().runAsync()
}
public override init() {
self.primaryStorage = OWSPrimaryStorage.shared()
}
private func runAsync() {
SwiftAssertIsOnMainThread(#function)
DispatchQueue.global().async {
self.restoreAttachments()
}
}
private func restoreAttachments() {
let temporaryDirectory = NSTemporaryDirectory()
let jobTempDirPath = (temporaryDirectory as NSString).appendingPathComponent(NSUUID().uuidString)
guard OWSFileSystem.ensureDirectoryExists(jobTempDirPath) else {
Logger.error("\(logTag) could not create temp directory.")
return
}
self.jobTempDirPath = jobTempDirPath
let backupIO = OWSBackupIO(jobTempDirPath: jobTempDirPath)
let attachmentIds = OWSBackup.shared().attachmentIdsForLazyRestore()
guard attachmentIds.count > 0 else {
Logger.info("\(logTag) No attachments need lazy restore.")
return
}
Logger.info("\(logTag) Lazy restoring \(attachmentIds.count) attachments.")
self.tryToRestoreNextAttachment(attachmentIds: attachmentIds, backupIO: backupIO)
}
private func tryToRestoreNextAttachment(attachmentIds: [String], backupIO: OWSBackupIO) {
var attachmentIdsCopy = attachmentIds
guard let attachmentId = attachmentIdsCopy.last else {
// This job is done.
Logger.verbose("\(logTag) job is done.")
return
}
attachmentIdsCopy.removeLast()
guard let attachment = TSAttachmentStream.fetch(uniqueId: attachmentId) else {
Logger.warn("\(logTag) could not load attachment.")
// Not necessarily an error.
// The attachment might have been deleted since the job began.
// Continue trying to restore the other attachments.
tryToRestoreNextAttachment(attachmentIds: attachmentIds, backupIO: backupIO)
return
}
OWSBackup.shared().lazyRestoreAttachment(attachment,
backupIO: backupIO,
completion: { (success) in
if success {
Logger.info("\(self.logTag) restored attachment.")
} else {
Logger.warn("\(self.logTag) could not restore attachment.")
}
// Continue trying to restore the other attachments.
self.tryToRestoreNextAttachment(attachmentIds: attachmentIdsCopy, backupIO: backupIO)
})
}
}