Swipe-That_pic/Swipe That Pic/PhotosService.swift

99 lines
3.2 KiB
Swift
Raw Permalink Normal View History

2024-07-26 13:16:48 +00:00
//
// PhotosService.swift
// Swipe That Pic
//
// Created by Amine Bou on 27/07/2024.
//
import Foundation
import Photos
import UIKit
import SwiftData
import SwiftUI
class PhotosService: ObservableObject {
var notKept: PHFetchResult<PHAsset> = PHFetchResult()
@Published var one: PHAsset?
var modelContainer: ModelContainer
init(modelContainer: ModelContainer) {
self.modelContainer = modelContainer
}
var imageCachingManager = PHCachingImageManager()
@MainActor func fetchNotKeptPhotos() {
PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
switch status {
case .authorized:
self.fetchNotKeptPhotosAuthorized()
break;
@unknown default:
fatalError()
}
}
}
@MainActor func fetchNotKeptPhotosAuthorized() {
imageCachingManager.allowsCachingHighQualityImages = false
let fetchOptions = PHFetchOptions()
fetchOptions.includeHiddenAssets = false
do {
let items = try self.modelContainer.mainContext.fetch(FetchDescriptor<Item>())
if (items.count > 0) {
fetchOptions.predicate = NSPredicate(format: "NOT localIdentifier IN %@",
argumentArray: [items.map {$0.localIdentfier}])
}
} catch {
print("Can't get model")
}
fetchOptions.sortDescriptors = [
NSSortDescriptor(key: "creationDate", ascending: false)
]
DispatchQueue.main.async {
self.notKept = PHAsset.fetchAssets(with: .image, options: fetchOptions)
if (self.notKept.count > 0) {
self.one = self.notKept.object(at: Int.random(in: 0..<self.notKept.count))
} else {
self.one = nil
}
}
}
func fetchImage(
byLocalIdentifier localId: String,
targetSize: CGSize = PHImageManagerMaximumSize,
contentMode: PHImageContentMode = .default
) async throws -> UIImage? {
let results = PHAsset.fetchAssets(
withLocalIdentifiers: [localId],
options: nil
)
guard let asset = results.firstObject else {
fatalError("No asset")
}
let options = PHImageRequestOptions()
options.deliveryMode = .opportunistic
options.resizeMode = .fast
options.isNetworkAccessAllowed = true
options.isSynchronous = true
return try await withCheckedThrowingContinuation { [weak self] continuation in
/// Use the imageCachingManager to fetch the image
self?.imageCachingManager.requestImage(
for: asset,
targetSize: targetSize,
contentMode: contentMode,
options: options,
resultHandler: { image, info in
/// image is of type UIImage
if let error = info?[PHImageErrorKey] as? Error {
continuation.resume(throwing: error)
return
}
continuation.resume(returning: image)
}
)
}
}
}