Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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)
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)
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)
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)))
}
}
}
}