IceCubesApp/Packages/StatusKit/Sources/StatusKit/Editor/Components/UTTypeSupported.swift
2024-01-26 13:01:23 +01:00

170 lines
4.7 KiB
Swift

@preconcurrency import AVFoundation
import Foundation
import PhotosUI
import SwiftUI
import UIKit
import UniformTypeIdentifiers
extension StatusEditor {
@MainActor
struct UTTypeSupported {
let value: String
func loadItemContent(item: NSItemProvider) async throws -> Any? {
if let transferable = await getVideoTransferable(item: item) {
return transferable
} else if let transferable = await getGifTransferable(item: item) {
return transferable
} else if let transferable = await getImageTansferable(item: item) {
return transferable
} else {
let result = try await item.loadItem(forTypeIdentifier: value)
if let url = result as? URL {
return url.absoluteString
} else if let text = result as? String {
return text
} else if let image = result as? UIImage {
return image
}
}
return nil
}
private func getVideoTransferable(item: NSItemProvider) async -> MovieFileTranseferable? {
await withCheckedContinuation { continuation in
_ = item.loadTransferable(type: MovieFileTranseferable.self) { result in
switch result {
case let .success(success):
continuation.resume(with: .success(success))
case .failure:
continuation.resume(with: .success(nil))
}
}
}
}
private func getGifTransferable(item: NSItemProvider) async -> GifFileTranseferable? {
await withCheckedContinuation { continuation in
_ = item.loadTransferable(type: GifFileTranseferable.self) { result in
switch result {
case let .success(success):
continuation.resume(with: .success(success))
case .failure:
continuation.resume(with: .success(nil))
}
}
}
}
private func getImageTansferable(item: NSItemProvider) async -> ImageFileTranseferable? {
await withCheckedContinuation { continuation in
_ = item.loadTransferable(type: ImageFileTranseferable.self) { result in
switch result {
case let .success(success):
continuation.resume(with: .success(success))
case .failure:
continuation.resume(with: .success(nil))
}
}
}
}
}
}
extension StatusEditor {
final class MovieFileTranseferable: Transferable, Sendable {
let url: URL
init(url: URL) {
self.url = url
_ = url.startAccessingSecurityScopedResource()
}
deinit {
url.stopAccessingSecurityScopedResource()
}
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(importedContentType: .movie) { receivedTransferrable in
return MovieFileTranseferable(url: receivedTransferrable.localURL)
}
FileRepresentation(importedContentType: .video) { receivedTransferrable in
return MovieFileTranseferable(url: receivedTransferrable.localURL)
}
}
}
final class GifFileTranseferable: Transferable, Sendable {
let url: URL
init(url: URL) {
self.url = url
_ = url.startAccessingSecurityScopedResource()
}
deinit {
url.stopAccessingSecurityScopedResource()
}
var data: Data? {
try? Data(contentsOf: url)
}
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(importedContentType: .gif) { receivedTransferrable in
return GifFileTranseferable(url: receivedTransferrable.localURL)
}
}
}
}
public extension StatusEditor {
final class ImageFileTranseferable: Transferable, Sendable {
public let url: URL
init(url: URL) {
self.url = url
_ = url.startAccessingSecurityScopedResource()
}
deinit {
url.stopAccessingSecurityScopedResource()
}
public static var transferRepresentation: some TransferRepresentation {
FileRepresentation(importedContentType: .image) { receivedTransferrable in
return ImageFileTranseferable(url: receivedTransferrable.localURL)
}
}
}
}
public extension ReceivedTransferredFile {
var localURL: URL {
if self.isOriginalFile {
return file
}
let copy = URL.temporaryDirectory.appending(path: "\(UUID().uuidString).\(self.file.pathExtension)")
try? FileManager.default.copyItem(at: self.file, to: copy)
return copy
}
}
public extension URL {
func mimeType() -> String {
if let mimeType = UTType(filenameExtension: pathExtension)?.preferredMIMEType {
mimeType
} else {
"application/octet-stream"
}
}
}
extension UIImage {
func resized(to size: CGSize) -> UIImage {
UIGraphicsImageRenderer(size: size).image { _ in
draw(in: CGRect(origin: .zero, size: size))
}
}
}