72 lines
2.6 KiB
Swift
72 lines
2.6 KiB
Swift
import Photos
|
|
import UIKit
|
|
|
|
struct ScreenshotCandidate: Identifiable {
|
|
let id: String
|
|
let asset: PHAsset
|
|
let capturedAt: Date
|
|
}
|
|
|
|
@MainActor
|
|
enum ScreenshotLibraryService {
|
|
static func requestAccess() async -> PHAuthorizationStatus {
|
|
let current = PHPhotoLibrary.authorizationStatus(for: .readWrite)
|
|
guard current == .notDetermined else { return current }
|
|
return await withCheckedContinuation { continuation in
|
|
PHPhotoLibrary.requestAuthorization(for: .readWrite) { result in
|
|
continuation.resume(returning: result)
|
|
}
|
|
}
|
|
}
|
|
|
|
static func recentScreenshots(limit: Int = 30) -> [ScreenshotCandidate] {
|
|
let options = PHFetchOptions()
|
|
options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
|
|
let assets = PHAsset.fetchAssets(with: .image, options: options)
|
|
var screenshots: [ScreenshotCandidate] = []
|
|
for index in 0..<assets.count {
|
|
let asset = assets.object(at: index)
|
|
guard asset.mediaSubtypes.contains(.photoScreenshot) else { continue }
|
|
screenshots.append(ScreenshotCandidate(
|
|
id: asset.localIdentifier,
|
|
asset: asset,
|
|
capturedAt: asset.creationDate ?? .now
|
|
))
|
|
if screenshots.count >= limit { break }
|
|
}
|
|
return screenshots
|
|
}
|
|
|
|
static func thumbnail(for asset: PHAsset) async -> UIImage? {
|
|
await withCheckedContinuation { continuation in
|
|
let options = PHImageRequestOptions()
|
|
options.deliveryMode = .highQualityFormat
|
|
options.resizeMode = .fast
|
|
options.isNetworkAccessAllowed = false
|
|
PHImageManager.default().requestImage(
|
|
for: asset,
|
|
targetSize: CGSize(width: 300, height: 300),
|
|
contentMode: .aspectFill,
|
|
options: options
|
|
) { image, _ in
|
|
continuation.resume(returning: image)
|
|
}
|
|
}
|
|
}
|
|
|
|
static func imageData(for asset: PHAsset) async throws -> Data {
|
|
try await withCheckedThrowingContinuation { continuation in
|
|
let options = PHImageRequestOptions()
|
|
options.deliveryMode = .highQualityFormat
|
|
options.isNetworkAccessAllowed = true
|
|
PHImageManager.default().requestImageDataAndOrientation(for: asset, options: options) { data, _, _, _ in
|
|
if let data {
|
|
continuation.resume(returning: data)
|
|
} else {
|
|
continuation.resume(throwing: ImportError.invalidImage)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|