import HUD import UIKit import Models import Shared import Combine import BackupFeature import DependencyInjection import iCloudFeature import DropboxFeature import GoogleDriveFeature final class RestoreListViewModel { @Dependency private var icloud: iCloudInterface @Dependency private var dropbox: DropboxInterface @Dependency private var drive: GoogleDriveInterface var hud: AnyPublisher<HUDStatus, Never> { hudSubject.eraseToAnyPublisher() } var didFetchBackup: AnyPublisher<RestoreSettings, Never> { backupSubject.eraseToAnyPublisher() } private var dropboxAuthCancellable: AnyCancellable? private let hudSubject = PassthroughSubject<HUDStatus, Never>() private let backupSubject = PassthroughSubject<RestoreSettings, Never>() func didTapCloud(_ cloudService: CloudService, from parent: UIViewController) { switch cloudService { case .drive: didRequestDriveAuthorization(from: parent) case .icloud: didRequestICloudAuthorization() case .dropbox: didRequestDropboxAuthorization(from: parent) } } private func didRequestDriveAuthorization(from controller: UIViewController) { drive.authorize(presenting: controller) { authResult in switch authResult { case .success: self.hudSubject.send(.on(nil)) self.drive.downloadMetadata { downloadResult in switch downloadResult { case .success(let metadata): var backup: Backup? if let metadata = metadata { backup = .init(id: metadata.identifier, date: metadata.modifiedDate, size: metadata.size) } self.hudSubject.send(.none) self.backupSubject.send(RestoreSettings(backup: backup, cloudService: .drive)) case .failure(let error): self.hudSubject.send(.error(.init(with: error))) } } case .failure(let error): self.hudSubject.send(.error(.init(with: error))) } } } private func didRequestICloudAuthorization() { if icloud.isAuthorized() { self.hudSubject.send(.on(nil)) icloud.downloadMetadata { result in switch result { case .success(let metadata): var backup: Backup? if let metadata = metadata { backup = .init(id: metadata.path, date: metadata.modifiedDate, size: metadata.size) } self.hudSubject.send(.none) self.backupSubject.send(RestoreSettings(backup: backup, cloudService: .icloud)) case .failure(let error): self.hudSubject.send(.error(.init(with: error))) } } } else { /// This could be an alert controller asking if user wants to enable/deeplink /// icloud.openSettings() } } private func didRequestDropboxAuthorization(from controller: UIViewController) { dropboxAuthCancellable = dropbox.authorize(presenting: controller) .receive(on: DispatchQueue.main) .sink { [unowned self] authResult in switch authResult { case .success(let bool): guard bool == true else { return } self.hudSubject.send(.on(nil)) dropbox.downloadMetadata { metadataResult in switch metadataResult { case .success(let metadata): var backup: Backup? if let metadata = metadata { backup = .init(id: metadata.path, date: metadata.modifiedDate, size: metadata.size) } self.hudSubject.send(.none) self.backupSubject.send(RestoreSettings(backup: backup, cloudService: .dropbox)) case .failure(let error): self.hudSubject.send(.error(.init(with: error))) } } case .failure(let error): self.hudSubject.send(.error(.init(with: error))) } } } }