diff --git a/ServiceLayer/Sources/ServiceLayer/Services/MediaProcessingService.swift b/ServiceLayer/Sources/ServiceLayer/Services/MediaProcessingService.swift index 7bf4fa5..807b548 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/MediaProcessingService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/MediaProcessingService.swift @@ -21,51 +21,59 @@ public extension MediaProcessingService { static func dataAndMimeType(itemProvider: NSItemProvider) -> AnyPublisher<(data: Data, mimeType: String), Error> { let registeredTypes = itemProvider.registeredTypeIdentifiers.compactMap(UTType.init) - let uniformType: UTType let mimeType: String + let dataPublisher: AnyPublisher - if let uniformTypeWithUploadableMimeType = registeredTypes.first(where: { + if let uniformType = registeredTypes.first(where: { guard let mimeType = $0.preferredMIMEType else { return false } return Self.uploadableMimeTypes.contains(mimeType) - }), let preferredMIMEType = uniformTypeWithUploadableMimeType.preferredMIMEType { - uniformType = uniformTypeWithUploadableMimeType + }), let preferredMIMEType = uniformType.preferredMIMEType { mimeType = preferredMIMEType - } else if registeredTypes == [UTType.image], let pngMIMEType = UTType.png.preferredMIMEType { - uniformType = .image + dataPublisher = Future { promise in + itemProvider.loadFileRepresentation(forTypeIdentifier: uniformType.identifier) { url, error in + if let error = error { + promise(.failure(error)) + } else if let url = url { + if uniformType.conforms(to: .image) && uniformType != .gif { + promise(imageData(url: url, type: uniformType)) + } else { + promise(Result { try Data(contentsOf: url) }) + } + } else { + promise(.failure(MediaProcessingError.fileURLNotFound)) + } + } + } + .eraseToAnyPublisher() + } 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() { + do { + let url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) + .appendingPathComponent(UUID().uuidString) + + try data.write(to: url) + + promise(imageData(url: url, type: .png)) + } catch { + promise(.failure(error)) + } + } else { + promise(.failure(MediaProcessingError.fileURLNotFound)) + } + } + } + .eraseToAnyPublisher() } else { return Fail(error: MediaProcessingError.invalidMimeType).eraseToAnyPublisher() } - return Future { promise in - itemProvider.loadItem(forTypeIdentifier: uniformType.identifier, options: nil) { item, error in - if let error = error { - promise(.failure(error)) - } else if let url = item as? URL { - if uniformType.conforms(to: .image) && uniformType != .gif { - promise(imageData(url: url, type: uniformType)) - } else { - promise(Result { try Data(contentsOf: url) }) - } - } else if let image = item as? UIImage, let data = image.pngData() { // screenshots - do { - let url = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) - .appendingPathComponent(UUID().uuidString) - - try data.write(to: url) - - promise(imageData(url: url, type: .png)) - } catch { - promise(.failure(error)) - } - } else { - promise(.failure(MediaProcessingError.fileURLNotFound)) - } - } - } - .map { (data: $0, mimeType: mimeType) } - .eraseToAnyPublisher() + return dataPublisher.map { (data: $0, mimeType: mimeType) }.eraseToAnyPublisher() } }