Home > Back-end >  Firebase storage. Download array of images
Firebase storage. Download array of images

Time:05-29

I'm trying to download some images from Firebase Storage folder and pus it into my model Rules Firebase Folder Images in folder

My model is here. Instead of String (1,2,3,4,5) I have to use images from folder that has the same String names

struct ImageModel {
    var images: String
    var index: Int
    var imageLabel: String
    var description: String
    var comment = [String]()
}

class Model {
   static var imageModel = [
        ImageModel(images: "1", index: 0, imageLabel: "MDA", description: "description", comment: []),
        ImageModel(images: "2", index: 1, imageLabel: "Picture!", description: "some description.", comment: []),
        ImageModel(images: "3", index: 2, imageLabel: "What is this??", description: "description", comment: []),
        ImageModel(images: "4", index: 3, imageLabel: "A long named picture", description: "description", comment: []),
    ]
}

I have found how to write a request

func uploadMedia() {
        let storageRef = Storage.storage().reference().child("pictures")
        let megaByte = Int64(1 * 1024 * 1024)
        
        storageRef.getData(maxSize: megaByte) { (data, error) in
            guard let data = data else { return }
            let image = UIImage(data: data)
            for i in Model.imageModel {
                i.images = image
            }
        }
    }

But it has some errors, like

Cannot assign to property: i is a let constant ... and .... Cannot assign value of type UIImage? to type String

How do I change my model or request?

I use my model in CollectionViewCell. So I have collectionView and Cell inside if it. Cell has Image and Name. This image I have to get from Firebase Storage and name I already have in my model. The reason is using Storage that my images can changes sometimes

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.identifier, for: indexPath) as? CollectionViewCell else { return UICollectionViewCell() }
        cell.configureCollectionViewCell(picture: UIImage(named: String(Model.imageModel[indexPath.row].images))!, imageLabel: Model.imageModel[indexPath.row].imageLabel)
        return cell
    }

UPD:

I change my model to:

struct ImageModel {
    var images: UIImage
    var index: Int
    var imageLabel: String
    var description: String
    var comment = [String]()
}

class Model {
   static var imageModel = [
    ImageModel(images: UIImage(), index: 0, imageLabel: "MDA", description: "description", comment: []),
    ImageModel(images: UIImage(), index: 1, imageLabel: "Picture!", description: "some description.", comment: []),
    ImageModel(images: UIImage(), index: 2, imageLabel: "What is this??", description: "description", comment: []),
    ImageModel(images: UIImage(), index: 3, imageLabel: "A long named picture", description: "description", comment: []),
    ]
}

Then I put method to ViewWillAppear and trying to get error or result in it

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.uploadMedia()
    }
    
    func uploadMedia() {
        let storageRef = Storage.storage().reference().child("pictures")
        let megaByte = Int64(1 * 1024 * 1024)
        
        storageRef.getData(maxSize: megaByte) { (data, error) in
            guard let data = data else { return }
            let image = UIImage(data: data)
            for (index, i) in Model.imageModel.enumerated() {
                Model.imageModel[index].images = image!
            }
            guard let error = error else  { return }
            print(error.localizedDescription)
        }
    }

And Nothing happens, logs are empty

2022-05-29 20:20:09.668785 0700 diplom[14378:13214993] [boringssl] boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics

Also I have method that helps me to save Model to another Model. Thats why I wanted to use String in my Model

Here it is.. CollectionView prepare for Detail VC

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let vc = DetailVC()
        vc.picture = UIImageView(image: Model.imageModel[indexPath.row].images)
        vc.imageLbel.text = Model.imageModel[indexPath.row].imageLabel
        vc.pictureNamed = Model.imageModel[indexPath.row].images
        vc.index = Model.imageModel[indexPath.row].index
        vc.descripLabel.text = Model.imageModel[indexPath.row].description
        self.navigationController?.pushViewController(vc, animated: true)
    }

Detail VC property

 var pictureNamed = String()

Model of Saved Collection Cell

struct savedCategory: Codable {
    var images: String
    var index: Int
    var imageLabel: String
    var description: String
    var comment = [String]()
}


class SavedCategoryModel {
    static var categoryModel: [savedCategory] = []
}

UserDefaults where I use codable model before

class UserDefaultsConfig {
    func saveData() {
        let defaults = UserDefaults.standard
        defaults.set(try? PropertyListEncoder().encode(SavedCategoryModel.categoryModel), forKey:"SavedStringArray")
    }
    func showList() {
        let defaults = UserDefaults.standard
        if let data = defaults.value(forKey:"SavedStringArray") as? Data { SavedCategoryModel.categoryModel = try! PropertyListDecoder().decode(Array<savedCategory>.self, from: data) }
    }
}

And here is my method. So there are a lot of changes... Is any resolution to get string of image?

@objc func savePicture() {
        let newArray = savedCategory(images: self.pictureNamed, index: index, imageLabel: self.imageLbel.text!, description: self.descripLabel.text ?? "empty", comment: Model.imageModel[index].comment)
        SavedCategoryModel.categoryModel.append(newArray)
        self.userDefaults.saveData()
        self.userDefaults.showList()
    }

CodePudding user response:

You want to access the array of images directly, not the reference to each item.

for (index, i) in Model.imageModel.enumerated() {
    Model.imageModel[index].images = image
}

Also, your images property accepts a String, as defined here:

var images: String

But you're trying to assign it a UIImage. I'm not sure what you're trying to add to the ImageModel, maybe you can elaborate?

Response to updated question:

First, allow your struct to accept images as a UIImage:

struct ImageModel {
    var images: UIImage // <-- from String to UIImage
    var index: Int
    var imageLabel: String
    var description: String
    var comment = [String]()
}

Then, change this line:

cell.configureCollectionViewCell(picture: UIImage(named: String(Model.imageModel[indexPath.row].images))!, imageLabel: Model.imageModel[indexPath.row].imageLabel)

To:

cell.configureCollectionViewCell(picture: Model.imageModel[indexPath.row].images, imageLabel: Model.imageModel[indexPath.row].imageLabel)

And one final suggestion, it seems you're storing only 1 image inside ImageModel.images, so maybe change the variable name to singular image like so:

struct ImageModel {
    var image: UIImage // <-- from String to UIImage
    var index: Int
    var imageLabel: String
    var description: String
    var comment = [String]()
}

Let me know this makes sense

  • Related