Skip to content

Commit

Permalink
fix(UTItemProviderFileRepresentation): Correct progress handlign.
Browse files Browse the repository at this point in the history
tests(UTItemProviderFileRepresentation): Test progress of tasks to be correct
  • Loading branch information
adrien-coye committed Jul 21, 2023
1 parent a86c6ae commit a71178a
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ import InfomaniakDI
/// Something that can provide a `Progress` and an async `Result` in order to load an url from a `NSItemProvider`
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public final class ItemProviderFileRepresentation: NSObject, ProgressResultable {
/// Progress increment size
private static let progressStep: Int64 = 1

/// Number of steps to complete the task
private static let totalSteps: Int64 = 2

/// Something to transform events to a nice `async Result`
private let flowToAsync = FlowToAsyncResult<Success>()

Expand All @@ -49,8 +55,7 @@ public final class ItemProviderFileRepresentation: NSObject, ProgressResultable
throw ErrorDomain.UTINotFound
}

// Keep compiler happy
progress = Progress(totalUnitCount: 1)
progress = Progress(totalUnitCount: Self.totalSteps)

super.init()

Expand All @@ -61,8 +66,13 @@ public final class ItemProviderFileRepresentation: NSObject, ProgressResultable
preferredImageFileFormat: preferredImageFileFormat
)

// Set progress and hook completion closure to a combine pipe
progress = itemProvider.loadFileRepresentation(forTypeIdentifier: fileIdentifierToUse) { [self] fileProviderURL, error in
// Set progress and hook completion closure
let completionProgress = Progress(totalUnitCount: Self.progressStep)
let loadURLProgress = itemProvider.loadFileRepresentation(forTypeIdentifier: fileIdentifierToUse) { [self] fileProviderURL, error in
defer {
completionProgress.completedUnitCount += Self.progressStep
}

guard let fileProviderURL, error == nil else {
flowToAsync.sendFailure(error ?? ErrorDomain.UnableToLoadFile)
return
Expand All @@ -84,6 +94,8 @@ public final class ItemProviderFileRepresentation: NSObject, ProgressResultable
flowToAsync.sendFailure(error)
}
}
progress.addChild(loadURLProgress, withPendingUnitCount: Self.progressStep)
progress.addChild(completionProgress, withPendingUnitCount: Self.progressStep)
}

// MARK: ProgressResultable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import InfomaniakDI
/// Something that can provide a `Progress` and an async `Result` in order to make a raw text file from a `NSItemProvider`
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public final class ItemProviderTextRepresentation: NSObject, ProgressResultable {
/// Progress increment size
private static let progressStep: Int64 = 1

/// Something to transform events to a nice `async Result`
private let flowToAsync = FlowToAsyncResult<Success>()

Expand All @@ -40,15 +43,12 @@ public final class ItemProviderTextRepresentation: NSObject, ProgressResultable
public typealias Success = URL
public typealias Failure = Error

private static let progressStep: Int64 = 1

public init(from itemProvider: NSItemProvider) throws {
guard let typeIdentifier = itemProvider.registeredTypeIdentifiers.first else {
throw ErrorDomain.UTINotFound
}

// Keep compiler happy
progress = Progress(totalUnitCount: 1)
progress = Progress(totalUnitCount: Self.progressStep)

super.init()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ import InfomaniakDI
/// Something that can provide a `Progress` and an async `Result` in order to make a webloc plist from a `NSItemProvider`
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public final class ItemProviderWeblocRepresentation: NSObject, ProgressResultable {
/// Progress increment size
private static let progressStep: Int64 = 1

/// Number of steps to complete the task
private static let totalSteps: Int64 = 2

/// Something to transform events to a nice `async Result`
private let flowToAsync = FlowToAsyncResult<Success>()

Expand All @@ -39,12 +45,16 @@ public final class ItemProviderWeblocRepresentation: NSObject, ProgressResultabl
public typealias Failure = Error

public init(from itemProvider: NSItemProvider) throws {
// Keep compiler happy
progress = Progress(totalUnitCount: 1)
progress = Progress(totalUnitCount: Self.totalSteps)

super.init()

progress = itemProvider.loadObject(ofClass: URL.self) { [self] path, error in
let completionProgress = Progress(totalUnitCount: Self.progressStep)
let loadURLProgress = itemProvider.loadObject(ofClass: URL.self) { [self] path, error in
defer {
completionProgress.completedUnitCount += Self.progressStep
}

guard error == nil, let path: URL = path else {
let error: Error = error ?? ErrorDomain.unableToLoadURLForObject
flowToAsync.sendFailure(error)
Expand All @@ -71,6 +81,8 @@ public final class ItemProviderWeblocRepresentation: NSObject, ProgressResultabl
flowToAsync.sendFailure(error)
}
}
progress.addChild(loadURLProgress, withPendingUnitCount: Self.progressStep)
progress.addChild(completionProgress, withPendingUnitCount: Self.progressStep)
}

// MARK: ProgressResultable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ import InfomaniakDI
/// Something that can provide a `Progress` and an async `Result` in order to make a zip from a `NSItemProvider`
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public final class ItemProviderZipRepresentation: NSObject, ProgressResultable {
/// Coordinator for file operations
let coordinator = NSFileCoordinator()

/// Progress increment size
private static let progressStep: Int64 = 1

/// Number of steps to complete the task
private static let totalSteps: Int64 = 2

/// Something to transform events to a nice `async Result`
private let flowToAsync = FlowToAsyncResult<Success>()

Expand All @@ -40,24 +49,21 @@ public final class ItemProviderZipRepresentation: NSObject, ProgressResultable {
public typealias Success = URL
public typealias Failure = Error

private static let progressStep: Int64 = 1

public init(from itemProvider: NSItemProvider) throws {
// It must be a directory for the OS to zip it for us, a file returns a file
guard itemProvider.underlyingType == .isDirectory else {
throw ErrorDomain.notADirectory
}

// Keep compiler happy
progress = Progress(totalUnitCount: 1)
progress = Progress(totalUnitCount: Self.totalSteps)

super.init()

let coordinator = NSFileCoordinator()

progress = itemProvider.loadObject(ofClass: URL.self) { [self] path, error in
let completionProgress = Progress(totalUnitCount: Self.progressStep)
let loadURLProgress = itemProvider.loadObject(ofClass: URL.self) { [self] path, error in
guard error == nil, let path: URL = path else {
flowToAsync.sendFailure(error ?? ErrorDomain.unableToLoadURLForObject)
completionProgress.completedUnitCount += Self.progressStep
return
}

Expand All @@ -66,13 +72,13 @@ public final class ItemProviderZipRepresentation: NSObject, ProgressResultable {
// > If you’d like to see such support [ie. for NSProgress] added in the future, I encourage you to file an
// enhancement request

// Minimalist progress file processing support
let childProgress = Progress()
progress.addChild(childProgress, withPendingUnitCount: Self.progressStep)

// compress content of folder and move it somewhere we can safely store it for upload
var error: NSError?
coordinator.coordinate(readingItemAt: path, options: [.forUploading], error: &error) { zipURL in
defer {
completionProgress.completedUnitCount += Self.progressStep
}

do {
@InjectService var pathProvider: AppGroupPathProvidable
let tmpDirectoryURL = pathProvider.tmpDirectoryURL
Expand All @@ -87,9 +93,10 @@ public final class ItemProviderZipRepresentation: NSObject, ProgressResultable {
} catch {
self.flowToAsync.sendFailure(error)
}
childProgress.completedUnitCount += Self.progressStep
}
}
progress.addChild(loadURLProgress, withPendingUnitCount: Self.progressStep)
progress.addChild(completionProgress, withPendingUnitCount: Self.progressStep)
}

// MARK: ProgressResultable
Expand Down
Loading

0 comments on commit a71178a

Please sign in to comment.