import Foundation final class FileStore { static let shared = FileStore() static var fileFolder: URL { // swiftlint:disable:next force_unwrapping let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let subdirectoryURL = documentsURL.appendingPathComponent(Const.fileFolder) if !FileManager.default.fileExists(atPath: subdirectoryURL.path) { try? FileManager.default.createDirectory(at: subdirectoryURL, withIntermediateDirectories: true, attributes: nil) } return subdirectoryURL } func storeCaptured(messageId: String, _ data: Data, _ type: GalleryMediaType) async throws -> (String, AttachmentType) { try await Task { // local name let fileId = UUID().uuidString let localName: String let msgType: AttachmentType switch type { case .photo: localName = "\(messageId)_\(fileId).jpg" msgType = .image case .video: localName = "\(messageId)_\(fileId).mov" msgType = .video } // save let localUrl = FileStore.fileFolder.appendingPathComponent(localName) try data.write(to: localUrl) return (localName, msgType) }.value } } // import Foundation // import Photos // import UIKit // // final class FileProcessing { // static let shared = FileProcessing() // // static var fileFolder: URL { // // swiftlint:disable:next force_unwrapping // let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! // let subdirectoryURL = documentsURL.appendingPathComponent(Const.fileFolder) // if !FileManager.default.fileExists(atPath: subdirectoryURL.path) { // try? FileManager.default.createDirectory(at: subdirectoryURL, withIntermediateDirectories: true, attributes: nil) // } // return subdirectoryURL // } // // func createThumbnail(localName: String) -> String? { // let thumbnailFileName = "thumb_\(localName)" // let thumbnailUrl = FileProcessing.fileFolder.appendingPathComponent(thumbnailFileName) // let localUrl = FileProcessing.fileFolder.appendingPathComponent(localName) // // // check if thumbnail already exists // if FileManager.default.fileExists(atPath: thumbnailUrl.path) { // return thumbnailFileName // } // // // create thumbnail if not exists // switch localName.attachmentType { // case .image: // guard let image = UIImage(contentsOfFile: localUrl.path) else { // print("FileProcessing: Error loading image: \(localUrl)") // return nil // } // let targetSize = CGSize(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize) // guard let thumbnail = scaleAndCropImage(image, targetSize) else { // print("FileProcessing: Error scaling image: \(localUrl)") // return nil // } // guard let data = thumbnail.pngData() else { // print("FileProcessing: Error converting thumbnail of \(localUrl) to data") // return nil // } // do { // try data.write(to: thumbnailUrl) // return thumbnailFileName // } catch { // print("FileProcessing: Error writing thumbnail: \(error)") // return nil // } // // default: // return nil // } // } // // func fetchGallery() -> [SharingGalleryItem] { // let items = syncGalleryEnumerate() // .map { // SharingGalleryItem( // id: $0.localIdentifier, // type: $0.mediaType == .image ? .photo : .video, // duration: $0.mediaType == .video ? $0.duration.minAndSec : nil // ) // } // return items // } // // func fillGalleryItemsThumbnails(items: [SharingGalleryItem]) -> [SharingGalleryItem] { // let ids = items // .filter { $0.thumbnail == nil } // .map { $0.id } // // let assets = syncGalleryEnumerate(ids) // return assets.compactMap { asset in // if asset.mediaType == .image { // return syncGalleryProcessImage(asset) { [weak self] image in // if let thumbnail = self?.scaleAndCropImage(image, CGSize(width: Const.galleryGridSize, height: Const.galleryGridSize)) { // let data = thumbnail.jpegData(compressionQuality: 1.0) ?? Data() // return SharingGalleryItem(id: asset.localIdentifier, type: .photo, thumbnail: data) // } else { // return nil // } // } // } else if asset.mediaType == .video { // return syncGalleryProcessVideo(asset) { [weak self] avAsset in // // swiftlint:disable:next force_cast // let assetURL = avAsset as! AVURLAsset // let url = assetURL.url // if let thumbnail = self?.generateVideoThumbnail(url, CGSize(width: Const.galleryGridSize, height: Const.galleryGridSize)) { // let data = thumbnail.jpegData(compressionQuality: 1.0) ?? Data() // return SharingGalleryItem( // id: asset.localIdentifier, // type: .video, // thumbnail: data, // duration: asset.duration.minAndSec // ) // } else { // return nil // } // } // } else { // return nil // } // } // } // // // This function also creates new ids for messages for each new attachment // func copyGalleryItemsForUploading(items: [SharingGalleryItem]) -> [(String, String)] { // let assets = syncGalleryEnumerate(items.map { $0.id }) // return assets // .compactMap { asset in // let newMessageId = UUID().uuidString // let fileId = UUID().uuidString // if asset.mediaType == .image { // return syncGalleryProcessImage(asset) { image in // let localName = "\(newMessageId)_\(fileId).jpg" // let localUrl = FileProcessing.fileFolder.appendingPathComponent(localName) // if let data = image.jpegData(compressionQuality: 1.0) { // do { // try data.write(to: localUrl) // return (newMessageId, localName) // } catch { // return nil // } // } else { // return nil // } // } // } else if asset.mediaType == .video { // return syncGalleryProcessVideo(asset) { avAsset in // // swiftlint:disable:next force_cast // let assetURL = avAsset as! AVURLAsset // let url = assetURL.url // let localName = "\(newMessageId)_\(fileId).mov" // let localUrl = FileProcessing.fileFolder.appendingPathComponent(localName) // do { // try FileManager.default.copyItem(at: url, to: localUrl) // return (newMessageId, localName) // } catch { // return nil // } // } // } else { // return nil // } // } // } // // // This function also creates new id for file from camera capturing // func copyCameraCapturedForUploading(media: Data, type: SharingCameraMediaType) -> (String, String)? { // let newMessageId = UUID().uuidString // let fileId = UUID().uuidString // let localName: String // switch type { // case .photo: // localName = "\(newMessageId)_\(fileId).jpg" // case .video: // localName = "\(newMessageId)_\(fileId).mov" // } // let localUrl = FileProcessing.fileFolder.appendingPathComponent(localName) // do { // try media.write(to: localUrl) // return (newMessageId, localName) // } catch { // return nil // } // } // // // This function also creates new id for file from document sharing // func copyDocumentsForUploading(data: [Data], extensions: [String]) -> [(String, String)] { // data.enumerated().compactMap { index, data in // let newMessageId = UUID().uuidString // let fileId = UUID().uuidString // let localName = "\(newMessageId)_\(fileId).\(extensions[index])" // let localUrl = FileProcessing.fileFolder.appendingPathComponent(localName) // do { // try data.write(to: localUrl) // return (newMessageId, localName) // } catch { // print("FileProcessing: Error writing document: \(error)") // return nil // } // } // } // } // // private extension FileProcessing { // func scaleAndCropImage(_ img: UIImage, _ size: CGSize) -> UIImage? { // let aspect = img.size.width / img.size.height // let targetAspect = size.width / size.height // var newWidth: CGFloat // var newHeight: CGFloat // if aspect < targetAspect { // newWidth = size.width // newHeight = size.width / aspect // } else { // newHeight = size.height // newWidth = size.height * aspect // } // // UIGraphicsBeginImageContextWithOptions(size, false, 0.0) // img.draw(in: CGRect(x: (size.width - newWidth) / 2, y: (size.height - newHeight) / 2, width: newWidth, height: newHeight)) // let newImage = UIGraphicsGetImageFromCurrentImageContext() // UIGraphicsEndImageContext() // // return newImage // } // // func syncGalleryEnumerate(_ ids: [String]? = nil) -> [PHAsset] { // var result: [PHAsset] = [] // // let group = DispatchGroup() // DispatchQueue.global(qos: .userInitiated).sync { // let fetchOptions = PHFetchOptions() // fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] // if let ids { // fetchOptions.predicate = NSPredicate(format: "localIdentifier IN %@", ids) // } // let assets = PHAsset.fetchAssets(with: fetchOptions) // assets.enumerateObjects { asset, _, _ in // group.enter() // result.append(asset) // group.leave() // } // } // group.wait() // return result // } // // func syncGalleryProcess(_ assets: [PHAsset], _ block: @escaping (PHAsset) -> T) -> [T] { // var result: [T] = [] // let group = DispatchGroup() // DispatchQueue.global(qos: .userInitiated).sync { // for asset in assets { // group.enter() // let res = block(asset) // result.append(res) // group.leave() // } // } // group.wait() // return result // } // // func syncGalleryProcessImage(_ asset: PHAsset, _ block: @escaping (UIImage) -> T?) -> T? { // var result: T? // let semaphore = DispatchSemaphore(value: 0) // DispatchQueue.global(qos: .userInitiated).sync { // let options = PHImageRequestOptions() // options.version = .original // options.isSynchronous = true // PHImageManager.default().requestImage( // for: asset, // targetSize: PHImageManagerMaximumSize, // contentMode: .aspectFill, // options: options // ) { image, _ in // if let image { // result = block(image) // } else { // result = nil // } // semaphore.signal() // } // } // semaphore.wait() // return result // } // // func syncGalleryProcessVideo(_ asset: PHAsset, _ block: @escaping (AVAsset) -> T?) -> T? { // var result: T? // let semaphore = DispatchSemaphore(value: 0) // _ = DispatchQueue.global(qos: .userInitiated).sync { // PHImageManager.default().requestAVAsset(forVideo: asset, options: nil) { avAsset, _, _ in // if let avAsset { // result = block(avAsset) // } else { // result = nil // } // semaphore.signal() // } // } // semaphore.wait() // return result // } // // func generateVideoThumbnail(_ url: URL, _ size: CGSize) -> UIImage? { // let asset = AVAsset(url: url) // let assetImgGenerate = AVAssetImageGenerator(asset: asset) // assetImgGenerate.appliesPreferredTrackTransform = true // let time = CMTimeMakeWithSeconds(Float64(1), preferredTimescale: 600) // do { // let cgImage = try assetImgGenerate.copyCGImage(at: time, actualTime: nil) // let image = UIImage(cgImage: cgImage) // return scaleAndCropImage(image, size) // } catch { // return nil // } // } // } // import Foundation // // final class DownloadManager { // static let shared = DownloadManager() // // private let urlSession: URLSession // private let downloadQueue = DispatchQueue(label: "com.example.downloadQueue") // private var activeDownloads = Set() // // init() { // let configuration = URLSessionConfiguration.default // urlSession = URLSession(configuration: configuration) // } // // func enqueueDownload(from url: URL, to localUrl: URL, completion: @escaping (Error?) -> Void) { // downloadQueue.async { // if self.activeDownloads.contains(url) { // print("Download for this file is already in queue.") // return // } // // self.activeDownloads.insert(url) // // let task = self.urlSession.downloadTask(with: url) { tempLocalUrl, _, error in // self.downloadQueue.async { // self.activeDownloads.remove(url) // // guard let tempLocalUrl = tempLocalUrl, error == nil else { // completion(error) // return // } // // do { // if FileManager.default.fileExists(atPath: localUrl.path) { // try FileManager.default.removeItem(at: localUrl) // } // let data = try Data(contentsOf: tempLocalUrl) // try data.write(to: localUrl) // completion(nil) // } catch let writeError { // completion(writeError) // } // } // } // task.resume() // } // } // }