From 2dd3260659f1a9735114687c8eadb2e25865b2a4 Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Thu, 4 Mar 2021 23:48:40 -0800 Subject: [PATCH] Refactoring --- .../Services/MediaProcessingService.swift | 90 ++++++++++--------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/ServiceLayer/Sources/ServiceLayer/Services/MediaProcessingService.swift b/ServiceLayer/Sources/ServiceLayer/Services/MediaProcessingService.swift index fbbe277..04238eb 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/MediaProcessingService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/MediaProcessingService.swift @@ -9,6 +9,7 @@ import UniformTypeIdentifiers enum MediaProcessingError: Error { case invalidMimeType case fileURLNotFound + case imageNotFound case unsupportedType case unableToCreateImageSource case unableToDownsample @@ -24,51 +25,16 @@ public extension MediaProcessingService { let mimeType: String let dataPublisher: AnyPublisher - if let uniformType = registeredTypes.first(where: { + if let type = registeredTypes.first(where: { guard let mimeType = $0.preferredMIMEType else { return false } - return Self.uploadableMimeTypes.contains(mimeType) - }), let preferredMIMEType = uniformType.preferredMIMEType { + return uploadableMimeTypes.contains(mimeType) + }), let preferredMIMEType = type.preferredMIMEType { mimeType = preferredMIMEType - dataPublisher = Future { promise in - itemProvider.loadFileRepresentation(forTypeIdentifier: uniformType.identifier) { url, error in - if let error = error { - promise(.failure(error)) - } else if let url = url { - promise(Result { - if uniformType.conforms(to: .image) && uniformType != .gif { - return try imageData(url: url, type: uniformType) - } else { - return try Data(contentsOf: url) - } - }) - } else { - promise(.failure(MediaProcessingError.fileURLNotFound)) - } - } - } - .eraseToAnyPublisher() + dataPublisher = fileRepresentationDataPublisher(itemProvider: itemProvider, type: type) } else if registeredTypes == [UTType.image], let pngMIMEType = UTType.png.preferredMIMEType { // screenshot mimeType = pngMIMEType - dataPublisher = Future { promise in - itemProvider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { item, error in - if let error = error { - promise(.failure(error)) - } else if let image = item as? UIImage, let data = image.pngData() { - promise(Result { - let url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) - .appendingPathComponent(UUID().uuidString) - - try data.write(to: url) - - return try imageData(url: url, type: .png) - }) - } else { - promise(.failure(MediaProcessingError.fileURLNotFound)) - } - } - } - .eraseToAnyPublisher() + dataPublisher = UIImagePNGDataPublisher(itemProvider: itemProvider) } else { return Fail(error: MediaProcessingError.invalidMimeType).eraseToAnyPublisher() } @@ -95,6 +61,50 @@ private extension MediaProcessingService { kCGImageSourceThumbnailMaxPixelSize: 1280 ] as CFDictionary + static func fileRepresentationDataPublisher(itemProvider: NSItemProvider, + type: UTType) -> AnyPublisher { + Future { promise in + itemProvider.loadFileRepresentation(forTypeIdentifier: type.identifier) { url, error in + if let error = error { + promise(.failure(error)) + } else if let url = url { + promise(Result { + if type.conforms(to: .image) && type != .gif { + return try imageData(url: url, type: type) + } else { + return try Data(contentsOf: url) + } + }) + } else { + promise(.failure(MediaProcessingError.fileURLNotFound)) + } + } + } + .eraseToAnyPublisher() + } + + static func UIImagePNGDataPublisher(itemProvider: NSItemProvider) -> AnyPublisher { + Future { promise in + itemProvider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { item, error in + if let error = error { + promise(.failure(error)) + } else if let image = item as? UIImage, let data = image.pngData() { + promise(Result { + let url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) + .appendingPathComponent(UUID().uuidString) + + try data.write(to: url) + + return try imageData(url: url, type: .png) + }) + } else { + promise(.failure(MediaProcessingError.imageNotFound)) + } + } + } + .eraseToAnyPublisher() + } + static func imageData(url: URL, type: UTType) throws -> Data { guard let source = CGImageSourceCreateWithURL(url as CFURL, Self.imageSourceOptions) else { throw MediaProcessingError.unableToCreateImageSource