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