Files
Schnappix/node_modules/expo-media-library/ios/next/objects/asset/Asset.swift
T

123 lines
3.3 KiB
Swift

import Foundation
import Photos
import UniformTypeIdentifiers
import ExpoModulesCore
class Asset: SharedObject {
let id: String
var phAsset: PHAsset?
init(id: String) {
self.id = id
}
func getHeight() async throws -> Int {
let phAsset = try await requirePHAsset()
return phAsset.pixelHeight
}
func getWidth() async throws -> Int {
let phAsset = try await requirePHAsset()
return phAsset.pixelWidth
}
func getDuration() async throws -> Double? {
let phAsset = try await requirePHAsset()
return phAsset.duration != 0 ? phAsset.duration : nil
}
func getFilename() async throws -> String {
let phAsset = try await requirePHAsset()
guard let filename = phAsset.value(forKey: "filename") as? String else {
throw FailedToGetPropertyException("filename")
}
return filename
}
func getCreationTime() async throws -> Int? {
let phAsset = try await requirePHAsset()
guard let date = phAsset.creationDate else {
return nil
}
return Int(date.timeIntervalSince1970)
}
func getModificationTime() async throws -> Int? {
let phAsset = try await requirePHAsset()
guard let date = phAsset.modificationDate else {
return nil
}
return Int(date.timeIntervalSince1970)
}
func getMediaType() async throws -> MediaTypeNext {
let phAsset = try await requirePHAsset()
return MediaTypeNext.from(phAsset.mediaType)
}
func getUri() async throws -> String {
let phAsset = try await requirePHAsset()
switch phAsset.mediaType {
case PHAssetMediaType.image:
let contentEditingInput = try await phAsset.requestContentEditingInput()
guard let url = contentEditingInput.fullSizeImageURL else {
throw FailedToGetPropertyException("uri")
}
return url.absoluteString
case PHAssetMediaType.video:
let options = PHVideoRequestOptions()
options.version = .original
guard let avAsset = try await PHImageManager.default()
.requestAVAsset(forVideo: phAsset, options: options) as? AVURLAsset else {
throw FailedToGetPropertyException("uri")
}
return avAsset.url.absoluteString
default:
throw FailedToGetPropertyException("uri")
}
}
func delete() async throws {
let assetToDelete = try await requirePHAsset()
try await AssetRepository.shared.delete(by: [assetToDelete])
}
private func requirePHAsset() async throws -> PHAsset {
try await loadPHAsset()
guard let phAsset else {
throw AssetNotFoundException(id)
}
return phAsset
}
private func loadPHAsset() async throws {
if phAsset != nil {
return
}
let options = PHFetchOptions()
options.includeHiddenAssets = true
options.includeAllBurstAssets = true
options.fetchLimit = 1
guard let fetchedAsset = PHAsset.fetchAssets(
withLocalIdentifiers: [self.id],
options: options
).firstObject else {
throw AssetNotFoundException(id)
}
self.phAsset = fetchedAsset
}
static func from(filePath: URL) async throws -> Asset {
guard FileManager.default.fileExists(atPath: filePath.path) else {
throw FailedToCreateAssetException("File does not exist at path: \(filePath.path)")
}
let id = try await AssetRepository.shared.add(from: filePath)
return Asset(id: id)
}
}