Saving and retrieving images with correct order - ios

I'm trying save some images to an array, and their name to another array as string with below code;
self.countryNamesArray.append(object["CountryName"] as! String)
let image = UIImage(data:imageData!)
self.countryImages.append(image!)
But it doesn't retrieve images with same order I saved while retrieve CountryNamesArray with correct order.
rowString = countryNamesArray[row]
myImageView.image = self.countryImages[row]
Should I use custom class to save images with string or are there any way to fix?

Related

Store sequence of images in CoreData

I tried to store images using CoreData. It is fine and I can store a single image. However how can I turn it to multiple images?
Currently, I have set the image field to Binary Data.
I save the image into the object by:
let imageData = UIImage(imageLiteralResourceName: "Dummy1").jpegData(compressionQuality: 1)
item.image = imageData
try? self.viewContext.save()
How can I turn it into an array of imageData that can store in CoreData?
I tried to do this but it fails:
let imageData1 = UIImage(imageLiteralResourceName: "Dummy1").jpegData(compressionQuality: 1)
let imageData2 = UIImage(imageLiteralResourceName: "Dummy2").jpegData(compressionQuality: 1)
item.image = [imageData1, imageData2]
try ? self.viewContext.save()
The compiler said that the attribute 'image' is Data? but not [Data]? type.
I have also tried to use the Type Transformable:
However, there is warning:
warning: Misconfigured Property: Items.imageArray is using a nil or insecure value transformer. Please switch to NSSecureUnarchiveFromDataTransformerName or a custom NSValueTransformer subclass of NSSecureUnarchiveFromDataTransformer
Any idea on the warning and how to resolve it?
On using the Transformable type, actually I can achieve this:
let imageData1 = UIImage(imageLiteralResourceName: "Dummy1").jpegData(compressionQuality: 1)
let imageData2 = UIImage(imageLiteralResourceName: "Dummy2").jpegData(compressionQuality: 1)
item.image = imageData1
item.imageArray = [imageData1!, imageData2!]
However, a few issues here:
It force to add ! to imageData, which indeed, should be optional in my case, I have no way to use ?? properly to give it a dummy imageData if that is found to be nil.
The same problem appear when I tried to display the array:
Image(uiImage: UIImage(data: (self.item.imageArray![0]))!)
.frame(width:300, height:300)
You can see that I have added ! to both imageArray! which can be nil and also the UIImage!
I would like to, instead provide default values for both cases, but I failed to use ?? to provide default value. Any idea?
You're trying to jam a square peg in a round hole. You can't assign an array of data into a data property or a transformable property because an array of data is neither data nor a transformable.
What you can do is to make your property a one-to-many relationship with another entity, let's call it ImageContainer, this other entity would have an imageData property. Now you could add as many images (within an image container) to your object.
Another alternative is to use a transformable value, which as I understand uses NSSecureCoding to transform your values into something CoreData can understand.
You should not save images directly in database, you will hit big performance issues.
Instead save the image name in the database and save the actual image with FileManager in the storage.
Then you can load the image/s from the file manager.

Swift ios only pick string values from array

In my app I have an array that looks like this:
var imgArray = [(Data, String)]()
It holds images and the images names and I append data by doing this:
if let firstImage = self.firstImage {
if let firstImageData = firstImage.compressImage() {
self.imgArray.append(firstImageData, self.randomImageName(length: 15))
}
}
Now I need to send all the image names inside that array using alamofire and I tried this:
for imgName in self.imgArray {
parameters["images[]"] = imgName.1
}
But my server responds by saying that images[] is empty, so I think that my ios code never sends an array named images[] containing the image names
Update
I changed the parameter to this:
parameters["images"] = [imgName.1]
This will upload one image, it seems like it overwrites the value each time so I need a way to grap all Strings from the imgArray array
Solution:
parameters["images"] = imgArray.map{$0.1}
This will add all of the image names from imgArray

how to add image literal to an array and show them?

I was trying to add image literals to array and display them as per the index.
Here is my code :
var images = [#imageLiteral(resourceName: "male-circle-128"),#imageLiteral(resourceName: "add_to_favourite-128"),#imageLiteral(resourceName: "28468-200"),#imageLiteral(resourceName: "progress_circular"),#imageLiteral(resourceName: "logout-1-128")]
and showing like this
cell!.imageView?.image = UIImage.init(cgImage: images[indexPath.row] as! CGImage)
got EXC_BAD_INSTRUCTION! what is the proper way to do this
let images:[UIImage] = [array of image literal goes here]
You can simply create array of image literals like:
var images = [#imageLiteral(resourceName: "image1"),#imageLiteral(resourceName: "image2"]
Why do you cast to CGImage , your literals are UIImage and you can use them without casting and even if you want CGImage use the initializer not casting.
let images = [literal images are here]
imageview.image = images[indexPath.row]

How to get a random image from a folder in swift?

So far I have created a folder of images and I am able to assign 1 of the images to a UIImageView.
But what I want to do now is create a random generator, that will pick a random image from the folder, so if I was to create a button, I could display all of the images separately and randomly on a single UIImageView.
However, this folder is going to have more than 100 images, so I don't want to hard code each one into an array. Also, the names of the image has to be unique to the image itself.
I have been searching online but cannot find information on how to code what will suit my needs. So how would I get and display a random image(s) from a folder in swift?
You can name your images like this
image_0
image_1
image_2
Then use this code to populate your UIImageView
let numberOfImages: UInt32 = 100
let random = arc4random_uniform(numberOfImages)
let imageName = "image_\(random)"
imageView.image = UIImage(named: imageName)
Update
Since you don't want to rename your images you can create a plist file (type Array) where you put all the names of your images
And finally
func loadRandomImage() {
let path = NSBundle.mainBundle().pathForResource("Images", ofType: "plist")!
let names = NSArray(contentsOfFile: path) as! [String]
let random = Int(arc4random_uniform(UInt32(names.count)))
let imageName = names[random]
imageView.image = UIImage(named: imageName)
}
You either need to create an array of string filenames and pick a random filename from the array, or you need to use the file manager (NSFileManager) to get a list of the files in your folder and then pick from THAT array. Nether is very difficult.

Save tableview textfields to an array of custom objects

I´m searching for a way to save the data a user enters in two textfields in a tableview. The user has to enter the name and the height of person in a tableview and I want to save it to a custom array.
struct PersonData {
var name: String
var height: Int
init(name: String, height: Int) {
self.name = name
self.height = height
}
}
I´ve searched and i found this Swift: retrieving text from a UITextField in a custom UITableViewCell and putting it in an array but still got two questions.
How i add item to my custom array? I try it with this:
personData[textField.tag].name = textField.text!
Isn´t a easier way to do it?
Thank you!!
If I understood your question properly then heres a possible solution.
You initialise an array of type PersonData. Then you make an object of type PersonData. Whenever you have some info, you store it in this object and append the object to the array created.
let array = [PersonData]()
let personDataObject = PersonData()
//After you store the values in the object you add the object to you array.
personDataObject.name = textField1.text
personDataObject.height = textField2.text //You need to convert this to Int. Try personDataObject.height = textField2.text as? Int or personDataObject.height = Int(textField2.text)
array.append(personDataObject)

Resources