How do you compress selected image to firebase with Swift's PhotoPicker?

70 Views Asked by At

I switched from using UIViewController Photo Picker to Swift's new native Photo Picker. The image picker itself works fine but uploading to firebase does not.

I want to compress the image to not fill up my Firebase storage too fast. With the old image picker, I had this code to do that :

guard let imageData = Image.jpegData(compressionQuality: 0.5) else 
{ return } 
ref.putData(imageData, metadata: nil) { _, error in 
    if let error = error { 
        print("DEBUG: Failed to upload image with error: \(error.localizedDescription)") 
        return 
    } 

but now I can't get the guard let statement working because "Type 'Image' has no member 'jpegData'" Since I'm not using UIImage anymore I'm not sure how to go about compressing the image.

ImageUploader file

import PhotosUI
import FirebaseStorage
import SwiftUI

enum UploadType {
    case profile
    case post
    case story
    
    var filePath: StorageReference {
        let filename = NSUUID().uuidString
        switch self {
        case .profile:
            return Storage.storage().reference(withPath: "/profile_image/\(filename)")
        case .post:
            return Storage.storage().reference(withPath: "/post_image/\(filename)")
        case .story:
            return Storage.storage().reference(withPath: "/story_image/\(filename)")
        }
    }} struct ImageUploader {
    
    static func uploadImage(image: Image?, type: UploadType, completion: @escaping(String) -> Void) {
        
        let ref = type.filePath
        
        guard let imageData = Image.jpegData(compressionQuality: 0.5) else { return }
        
        ref.putData(imageData, metadata: nil) { _, error in
            if let error = error {
                print("DEBUG: Failed to upload image with error: \(error.localizedDescription)")
                return
            }
            
            ref.downloadURL { imageUrl, _ in
                guard let imageUrl = imageUrl?.absoluteString else { return }
                completion(imageUrl)
            }
        }
    }
}

ImagePicker File - just in case

@MainActor
class ImagePicker: ObservableObject {
    
    @Published var image: Image?
    @Published var imageSelection: PhotosPickerItem? {
        
        didSet {
            if let imageSelection {
                Task {
                    try await loadTransferable(from: imageSelection)
                }
            }
        }
    }
    
    func loadTransferable(from imageSelection: PhotosPickerItem?) async throws {
        do {
            if let data = try await imageSelection?.loadTransferable(type: Data.self) {
                if let uiImage = UIImage(data: data) {
                    self.image = Image(uiImage: uiImage)
                }
            }
        } catch {
            print(error.localizedDescription)
            image = nil
        }
    }
}
0

There are 0 best solutions below