Skip to content

Commit 024232d

Browse files
committed
Merge branch 'release/2.2.1'
2 parents 6a50773 + 9a140ed commit 024232d

File tree

48 files changed

+1610
-327
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1610
-327
lines changed

Cryptomator.xcodeproj/project.pbxproj

+43-15
Large diffs are not rendered by default.

Cryptomator.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
"repositoryURL": "https://github.com/cryptomator/cloud-access-swift.git",
3434
"state": {
3535
"branch": null,
36-
"revision": "1db22e4ea17c85eaa98bfabf1fbf699fcf6e94e0",
37-
"version": "1.2.0"
36+
"revision": "fa5c2e9a9db0f91981e728679fca14005d230eac",
37+
"version": "1.2.1"
3838
}
3939
},
4040
{

Cryptomator/Purchase/Cells/TrialCell.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ struct TrialCellViewModel: Hashable {
7777
let formatter = DateFormatter()
7878
formatter.dateStyle = .short
7979
let formattedExpirationDate = formatter.string(for: expirationDate) ?? "Invalid Date"
80-
return "Expiration Date: \(formattedExpirationDate)"
80+
return String(format: LocalizedString.getValue("purchase.product.trial.expirationDate"), formattedExpirationDate)
8181
}
8282

8383
let expirationDate: Date

Cryptomator/Purchase/IAPViewController.swift

+4
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ class BaseIAPViewModel {
226226
return iapManager.buy(product).recover { error -> PurchaseTransaction in
227227
if (error as? SKError)?.code == .paymentCancelled {
228228
throw PurchaseError.paymentCancelled
229+
} else if (error as? SKError)?.code == .unknown {
230+
throw PurchaseError.unknown
229231
} else {
230232
throw error
231233
}
@@ -277,6 +279,8 @@ class BaseIAPViewModel {
277279
return iapManager.restore().recover { error -> RestoreTransactionsResult in
278280
if (error as? SKError)?.code == .paymentCancelled {
279281
throw PurchaseError.paymentCancelled
282+
} else if (error as? SKError)?.code == .unknown {
283+
throw PurchaseError.unknown
280284
} else {
281285
throw error
282286
}

Cryptomator/Purchase/PurchaseViewModel.swift

+13-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,21 @@ import Foundation
1111
import Promises
1212
import StoreKit
1313

14-
enum PurchaseError: Error {
14+
enum PurchaseError: LocalizedError {
1515
case unavailableProduct
1616
case paymentCancelled
17+
case unknown
18+
19+
public var errorDescription: String? {
20+
switch self {
21+
case .unavailableProduct:
22+
return nil // should never happen
23+
case .paymentCancelled:
24+
return nil // not needed since nothing should be shown
25+
case .unknown:
26+
return LocalizedString.getValue("purchase.error.unknown")
27+
}
28+
}
1729
}
1830

1931
class PurchaseViewModel: BaseIAPViewModel, ProductFetching {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// WebDAVAuthenticatorError+Localization.swift
3+
// CryptomatorCommonCore
4+
//
5+
// Created by Tobias Hagemann on 31.03.22.
6+
// Copyright © 2022 Skymatic GmbH. All rights reserved.
7+
//
8+
9+
import CryptomatorCloudAccessCore
10+
import Foundation
11+
12+
extension WebDAVAuthenticatorError: LocalizedError {
13+
public var errorDescription: String? {
14+
switch self {
15+
case .unsupportedProcotol:
16+
return LocalizedString.getValue("webDAVAuthenticator.error.unsupportedProtocol")
17+
case .untrustedCertificate:
18+
return LocalizedString.getValue("webDAVAuthenticator.error.untrustedCertificate")
19+
}
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// CloudPath+GetParent.swift
3+
// CryptomatorFileProvider
4+
//
5+
// Created by Philipp Schmid on 31.03.22.
6+
// Copyright © 2022 Skymatic GmbH. All rights reserved.
7+
//
8+
9+
import CryptomatorCloudAccessCore
10+
import Foundation
11+
12+
extension CloudPath {
13+
/// Returns the parent of the current path. Returns nil if the current path is already the root path.
14+
func getParent() -> CloudPath? {
15+
if path == "/" {
16+
return nil
17+
}
18+
return deletingLastPathComponent()
19+
}
20+
}

CryptomatorFileProvider/CloudTask/CloudTask.swift

+6
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ import Foundation
1212
protocol CloudTask {
1313
var itemMetadata: ItemMetadata { get }
1414
}
15+
16+
extension CloudTask {
17+
var cloudPath: CloudPath {
18+
return itemMetadata.cloudPath
19+
}
20+
}

CryptomatorFileProvider/FileProviderAdapter.swift

+57-33
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class FileProviderAdapter: FileProviderAdapterType {
4343
private let localURLProvider: LocalURLProviderType
4444
private let notificator: FileProviderItemUpdateDelegate?
4545
private let fullVersionChecker: FullVersionChecker
46+
private let workflowFactory: WorkflowFactoryLocking
4647

4748
init(uploadTaskManager: UploadTaskManager, cachedFileManager: CachedFileManager, itemMetadataManager: ItemMetadataManager, reparentTaskManager: ReparentTaskManager, deletionTaskManager: DeletionTaskManager, itemEnumerationTaskManager: ItemEnumerationTaskManager, downloadTaskManager: DownloadTaskManager, scheduler: WorkflowScheduler, provider: CloudProvider, notificator: FileProviderItemUpdateDelegate? = nil, localURLProvider: LocalURLProviderType, fullVersionChecker: FullVersionChecker = UserDefaultsFullVersionChecker.shared) {
4849
self.lastUnlockedDate = Date()
@@ -53,6 +54,15 @@ public class FileProviderAdapter: FileProviderAdapterType {
5354
self.deletionTaskManager = deletionTaskManager
5455
self.itemEnumerationTaskManager = itemEnumerationTaskManager
5556
self.downloadTaskManager = downloadTaskManager
57+
let factory = WorkflowFactory(provider: provider,
58+
uploadTaskManager: uploadTaskManager,
59+
cachedFileManager: cachedFileManager,
60+
itemMetadataManager: itemMetadataManager,
61+
reparentTaskManager: reparentTaskManager,
62+
deletionTaskManager: deletionTaskManager,
63+
itemEnumerationTaskManager: itemEnumerationTaskManager,
64+
downloadTaskManager: downloadTaskManager)
65+
self.workflowFactory = WorkflowFactoryLocking(lockManager: LockManager(), workflowFactory: factory)
5666
self.scheduler = scheduler
5767
self.provider = provider
5868
self.notificator = notificator
@@ -116,8 +126,7 @@ public class FileProviderAdapter: FileProviderAdapterType {
116126
} catch {
117127
return Promise(error)
118128
}
119-
let workflow = WorkflowFactory.createWorkflow(for: enumerationTask, provider: provider, itemMetadataManager: itemMetadataManager, cachedFileManager: cachedFileManager, reparentTaskManager: reparentTaskManager, uploadTaskManager: uploadTaskManager, deletionTaskManager: deletionTaskManager, itemEnumerationTaskManager: itemEnumerationTaskManager)
120-
return scheduler.schedule(workflow)
129+
return workflowFactory.createWorkflow(for: enumerationTask).then(scheduler.schedule)
121130
}
122131

123132
private func enumerateWorkingSet() -> Promise<FileProviderItemList> {
@@ -154,10 +163,15 @@ public class FileProviderAdapter: FileProviderAdapterType {
154163
}
155164
return completionHandler(nil, NSFileProviderError(.noSuchItem))
156165
}
157-
completionHandler(localItemImportResult.item, nil)
158-
166+
let localImportHandler: (Error?) -> Void = { error in
167+
if let error = error {
168+
completionHandler(nil, error)
169+
} else {
170+
completionHandler(localItemImportResult.item, nil)
171+
}
172+
}
159173
// Network Stuff
160-
self.uploadFile(taskRecord: localItemImportResult.uploadTaskRecord).then { item in
174+
self.uploadFile(taskRecord: localItemImportResult.uploadTaskRecord, completionHandler: localImportHandler).then { item in
161175
self.notificator?.signalUpdate(for: item)
162176
}.catch { error in
163177
DDLogError("importDocument uploadFile failed: \(error)")
@@ -252,15 +266,18 @@ public class FileProviderAdapter: FileProviderAdapterType {
252266
}
253267
}
254268

255-
func uploadFile(taskRecord: UploadTaskRecord) -> Promise<FileProviderItem> {
256-
let workflow: Workflow<FileProviderItem>
269+
func uploadFile(taskRecord: UploadTaskRecord, completionHandler: ((Error?) -> Void)? = nil) -> Promise<FileProviderItem> {
270+
let task: UploadTask
257271
do {
258-
let task = try uploadTaskManager.getTask(for: taskRecord)
259-
workflow = WorkflowFactory.createWorkflow(for: task, provider: provider, itemMetadataManager: itemMetadataManager, cachedFileManager: cachedFileManager, uploadTaskManager: uploadTaskManager)
272+
task = try uploadTaskManager.getTask(for: taskRecord)
260273
} catch {
274+
completionHandler?(error)
261275
return Promise(error)
262276
}
263-
return scheduler.schedule(workflow)
277+
return workflowFactory.createWorkflow(for: task).then { workflow -> Workflow<FileProviderItem> in
278+
completionHandler?(nil)
279+
return workflow
280+
}.then(scheduler.schedule)
264281
}
265282

266283
func registerFileInUploadQueue(with localURL: URL, itemMetadata: ItemMetadata) throws -> UploadTaskRecord {
@@ -293,12 +310,15 @@ public class FileProviderAdapter: FileProviderAdapterType {
293310
DDLogError("Create directory: createPlaceholderItemForFolder failed with error: \(error) ")
294311
return completionHandler(nil, error)
295312
}
296-
completionHandler(placeholderItem, nil)
313+
297314
let task = FolderCreationTask(itemMetadata: placeholderItem.metadata)
298-
let workflow = WorkflowFactory.createWorkflow(for: task, provider: provider, itemMetadataManager: itemMetadataManager)
299-
scheduler.schedule(workflow).then { item in
300-
self.notificator?.signalUpdate(for: item)
301-
}
315+
workflowFactory.createWorkflow(for: task).then { workflow -> Workflow<FileProviderItem> in
316+
completionHandler(placeholderItem, nil)
317+
return workflow
318+
}.then(scheduler.schedule)
319+
.then { item in
320+
self.notificator?.signalUpdate(for: item)
321+
}
302322
}
303323

304324
// MARK: Move Item
@@ -317,11 +337,13 @@ public class FileProviderAdapter: FileProviderAdapterType {
317337
} catch {
318338
return completionHandler(nil, error)
319339
}
320-
completionHandler(result.item, nil)
321-
let workflow = WorkflowFactory.createWorkflow(for: reparentTask, provider: provider, itemMetadataManager: itemMetadataManager, cachedFileManager: cachedFileManager, reparentTaskManager: reparentTaskManager)
322-
scheduler.schedule(workflow).then { item in
323-
self.notificator?.signalUpdate(for: item)
324-
}
340+
workflowFactory.createWorkflow(for: reparentTask).then { workflow -> Workflow<FileProviderItem> in
341+
completionHandler(result.item, nil)
342+
return workflow
343+
}.then(scheduler.schedule)
344+
.then { item in
345+
self.notificator?.signalUpdate(for: item)
346+
}
325347
}
326348

327349
public func reparentItem(withIdentifier itemIdentifier: NSFileProviderItemIdentifier, toParentItemWithIdentifier parentItemIdentifier: NSFileProviderItemIdentifier, newName: String?, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
@@ -339,10 +361,11 @@ public class FileProviderAdapter: FileProviderAdapterType {
339361
return completionHandler(nil, error)
340362
}
341363
completionHandler(result.item, nil)
342-
let workflow = WorkflowFactory.createWorkflow(for: reparentTask, provider: provider, itemMetadataManager: itemMetadataManager, cachedFileManager: cachedFileManager, reparentTaskManager: reparentTaskManager)
343-
scheduler.schedule(workflow).then { item in
344-
self.notificator?.signalUpdate(for: item)
345-
}
364+
workflowFactory.createWorkflow(for: reparentTask)
365+
.then(scheduler.schedule)
366+
.then { item in
367+
self.notificator?.signalUpdate(for: item)
368+
}
346369
}
347370

348371
/**
@@ -416,18 +439,20 @@ public class FileProviderAdapter: FileProviderAdapterType {
416439
completionHandler(error)
417440
return
418441
}
419-
let workflow: Workflow<Void>
442+
let deletionTask: DeletionTask
420443
do {
421-
let deletionTaskInfo = try deletionTaskManager.getTask(for: taskRecord)
422-
workflow = WorkflowFactory.createWorkflow(for: deletionTaskInfo, provider: provider, itemMetadataManager: itemMetadataManager)
444+
deletionTask = try deletionTaskManager.getTask(for: taskRecord)
423445
} catch {
424446
completionHandler(error)
425447
return
426448
}
427-
completionHandler(nil)
428-
scheduler.schedule(workflow).then {
429-
DDLogVerbose("DeleteItem success")
430-
}
449+
workflowFactory.createWorkflow(for: deletionTask).then { workflow -> Workflow<Void> in
450+
completionHandler(nil)
451+
return workflow
452+
}.then(scheduler.schedule)
453+
.then {
454+
DDLogVerbose("DeleteItem success")
455+
}
431456
}
432457

433458
/**
@@ -590,8 +615,7 @@ public class FileProviderAdapter: FileProviderAdapterType {
590615
} catch {
591616
return Promise(error)
592617
}
593-
let workflow = WorkflowFactory.createWorkflow(for: task, provider: provider, itemMetadataManager: itemMetadataManager, cachedFileManager: cachedFileManager, downloadTaskManager: downloadTaskManager)
594-
return scheduler.schedule(workflow).then { item -> Void in
618+
return workflowFactory.createWorkflow(for: task).then(scheduler.schedule).then { item -> Void in
595619
self.notificator?.signalUpdate(for: item)
596620
}
597621
}

0 commit comments

Comments
 (0)