IceCubesApp/Packages/StatusKit/Sources/StatusKit/Editor/Components/UTTypeSupported.swift

170 lines
4.7 KiB
Swift
Raw Normal View History

2024-01-06 17:43:26 +00:00
@preconcurrency import AVFoundation
import Foundation
import PhotosUI
import SwiftUI
import UIKit
import UniformTypeIdentifiers
extension StatusEditor {
@MainActor
2024-01-20 18:17:59 +00:00
struct UTTypeSupported {
let value: String
2024-01-06 17:43:26 +00:00
func loadItemContent(item: NSItemProvider) async throws -> Any? {
2024-01-20 18:17:59 +00:00
if let transferable = await getVideoTransferable(item: item) {
2024-01-06 17:43:26 +00:00
return transferable
2024-01-20 18:17:59 +00:00
} else if let transferable = await getGifTransferable(item: item) {
2024-01-06 17:43:26 +00:00
return transferable
2024-01-20 18:17:59 +00:00
} else if let transferable = await getImageTansferable(item: item) {
2024-01-06 17:43:26 +00:00
return transferable
} else {
2024-01-20 18:17:59 +00:00
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
}
2024-01-06 17:43:26 +00:00
}
2024-01-20 18:17:59 +00:00
return nil
2024-01-06 17:43:26 +00:00
}
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 {
2024-01-26 12:01:23 +00:00
final class MovieFileTranseferable: Transferable, Sendable {
2024-01-06 17:43:26 +00:00
let url: URL
2024-01-20 18:17:59 +00:00
init(url: URL) {
self.url = url
_ = url.startAccessingSecurityScopedResource()
}
deinit {
url.stopAccessingSecurityScopedResource()
}
2024-01-06 17:43:26 +00:00
static var transferRepresentation: some TransferRepresentation {
2024-01-20 18:17:59 +00:00
FileRepresentation(importedContentType: .movie) { receivedTransferrable in
return MovieFileTranseferable(url: receivedTransferrable.localURL)
2024-01-06 17:43:26 +00:00
}
2024-01-20 18:41:44 +00:00
FileRepresentation(importedContentType: .video) { receivedTransferrable in
return MovieFileTranseferable(url: receivedTransferrable.localURL)
}
2024-01-06 17:43:26 +00:00
}
}
2024-01-26 12:01:23 +00:00
final class GifFileTranseferable: Transferable, Sendable {
2024-01-06 17:43:26 +00:00
let url: URL
2024-01-20 18:17:59 +00:00
init(url: URL) {
self.url = url
_ = url.startAccessingSecurityScopedResource()
}
deinit {
url.stopAccessingSecurityScopedResource()
}
2024-01-06 17:43:26 +00:00
var data: Data? {
try? Data(contentsOf: url)
}
static var transferRepresentation: some TransferRepresentation {
2024-01-20 18:17:59 +00:00
FileRepresentation(importedContentType: .gif) { receivedTransferrable in
return GifFileTranseferable(url: receivedTransferrable.localURL)
2024-01-06 17:43:26 +00:00
}
}
}
}
public extension StatusEditor {
2024-01-20 18:17:59 +00:00
final class ImageFileTranseferable: Transferable, Sendable {
2024-01-06 17:43:26 +00:00
public let url: URL
2024-01-20 18:17:59 +00:00
init(url: URL) {
self.url = url
_ = url.startAccessingSecurityScopedResource()
}
deinit {
url.stopAccessingSecurityScopedResource()
}
2024-01-06 17:43:26 +00:00
public static var transferRepresentation: some TransferRepresentation {
2024-01-20 18:17:59 +00:00
FileRepresentation(importedContentType: .image) { receivedTransferrable in
return ImageFileTranseferable(url: receivedTransferrable.localURL)
2024-01-06 17:43:26 +00:00
}
}
}
}
public extension ReceivedTransferredFile {
var localURL: URL {
2024-01-20 18:17:59 +00:00
if self.isOriginalFile {
return file
}
2024-01-06 17:43:26 +00:00
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))
}
}
}