import AVFoundation import Photos import SwiftUI import UIKit class MediaManager: NSObject, ObservableObject { @Published var photos: [UIImage] = [] @Published var cameraFeed: UIImage? override init() { super.init() DispatchQueue.global(qos: .userInitiated).async { [weak self] in self?.fetchPhotos() self?.setupCameraFeed() } } private func fetchPhotos() { let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions) let manager = PHImageManager.default() let option = PHImageRequestOptions() option.isSynchronous = true assets.enumerateObjects { asset, _, _ in manager.requestImage(for: asset, targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: option) { image, _ in if let image = image { DispatchQueue.main.async { self.photos.append(image) } } } } } private func setupCameraFeed() { let captureSession = AVCaptureSession() captureSession.sessionPreset = .medium guard let captureDevice = AVCaptureDevice.default(for: .video) else { return } let deviceInput: AVCaptureDeviceInput do { deviceInput = try AVCaptureDeviceInput(device: captureDevice) } catch { return } if captureSession.canAddInput(deviceInput) { captureSession.addInput(deviceInput) } let videoOutput = AVCaptureVideoDataOutput() videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue")) if captureSession.canAddOutput(videoOutput) { captureSession.addOutput(videoOutput) } captureSession.startRunning() } } extension MediaManager: AVCaptureVideoDataOutputSampleBufferDelegate { func captureOutput(_: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from _: AVCaptureConnection) { guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return } let ciImage = CIImage(cvPixelBuffer: pixelBuffer) let context = CIContext() guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else { return } DispatchQueue.main.async { self.cameraFeed = UIImage(cgImage: cgImage) } } }