UIImage on swift can't check for nil - ios

I have the following code on Swift
var image = UIImage(contentsOfFile: filePath)
if image != nil {
return image
}
It used to work great, but now on Xcode Beta 6, this returns a warning
'UIImage' is not a subtype of 'NSString'
I don't know what to do, I tried different things like
if let image = UIImage(contentsOfFile: filePath) {
return image
}
But the error changes to:
Bound value in a conditional binding must be of Optional type
Is this a bug on Xcode6 beta 6 or am I doing something wrong?

Update
Swift now added the concept of failable initializers and UIImage is now one of them. The initializer returns an Optional so if the image cannot be created it will return nil.
Variables by default cannot be nil. That is why you are getting an error when trying to compare image to nil. You need to explicitly define your variable as optional:
let image: UIImage? = UIImage(contentsOfFile: filePath)
if image != nil {
return image!
}

The simplest way to check if an image has content (> nil) is:
if image.size.width != 0 { do someting}

func imageIsNullOrNot(imageName : UIImage)-> Bool
{
let size = CGSize(width: 0, height: 0)
if (imageName.size.width == size.width)
{
return false
}
else
{
return true
}
}
the Above method call Like as :
if (imageIsNullOrNot(selectedImage))
{
//image is not null
}
else
{
//image is null
}
here, i check image size.

Init, that you are call init?(contentsOfFile path: String) the ? means that it returns optional value.
You should check optional vars for nil before use it.
Shorter, than accepted answer and Swift-style way, than named Optional Chaining to do that:
if let image = UIImage(contentsOfFile: filePath) {
return image
}

You can check it's imageAsset like this:
if image.imageAsset != nil
{
// image is not null
}
else
{
//image is null
}

You can check for it's width, which would be 0 if no image is uploaded.
if(image.size.width != 0){
print("image found")
} else {
print("image is null")
}

Related

SwiftUI - Check If Image Exist

I am attempting to execute code if an image exist.
The issue is I am unable to capture the state of empty image call.
The result is I get an empty image, but would rather put a placeholder image if possible.
func procImage(inName: String) {
switch (inName) {
case inName:
imageName = inName.lowercased()
default:
imageName = "blank"
}
}
This check is easy but you need to be sure that default image always exists.
func getSafeImage(named: String) -> Image {
let uiImage = (UIImage(named: named) ?? UIImage(named: "Default.png"))!
return Image(uiImage: uiImage)
}
Try this code:
func procImage(inName: String) -> UIImage {
if let confirmedImage = UIImage(named: inName) {
return confirmedImage
} else {
return UIImage(named: "Default_Image.png")!
}
}
Thanks all for contributing.
The solutions on offer did not quite work in my case except for Moreno's solution, but offered a path to my solution.
I did not need to store the result of the check, but just validate the existence of the file.
So this is what I came up with which worked.
This may not be the optimal solution, so improved code will be welcomed.
func procImage(inName: String) {
let imageConvertToLowercase = inName.lowercased()
if getMember.firstName.lowercased() == imageConvertToLowercase {
if (UIImage(named: imageConvertToLowercase) != nil) {
imageName = imageConvertToLowercase
} else {
imageName = "blank"
}
}
}

swift compare multiple images to an array of images

I have 2 UIImageViews connected to an array of images
I'm trying compare both once they are displayed but doesn't seems to work.
I tried using imageArray[Image Literal] and also imageArray[image1.png, image2.png, image3.png, image4.png, image5.png]
I'm not sure what im doing wrong.
im not looking for the code although it may help but what im looking is for a someone to guide me to the right direction
#IBOutlet weak var 1ImageView: UIImageView!
#IBOutlet weak var 2ImageView: UIImageView!
let imageArray = [image1.png, image2.png, image3.png, image4.png, image5.png]
func any() {
if (1ImageView != nil) && (2ImageView != nil) && isEqual(image1.png) {
print("match!")
} else if ...// more if statements
…last if statement} else {
print(“no match!”)
}
#IBAction func buttonPressed(_ sender: IUButton) {
any()
}
If this is not possible is there a way to assign an identifier to each of the images inside the array..
sorry for the extra question.
there is one answer on comparing 2 images using NSData but Im not sure how to implement it to an array.
thanks and sorry but the newbie question.
image.isEqual(image) seems to be unreliable, despite what documentation says. If you don't need to make a pixel perfect comparison, converting image to a data and comparing those would be sufficient.
let image1 = UIImage(named: "image1.png")
let image2 = UIImage(named: "image2.png")
let imageData1 = image1?.pngData()
let imageData2 = image2?.pngData()
if imageData1 == imageData2 {
print("images are the same")
} else {
print("images are different")
}
Looking for a specific image inside an array can build on that:
// array of images referencing image files within an Xcode project
// it's not the best idea to force unwrap those, but for the sake of simplicity
let imageArray = [UIImage(named: "image1.png")!,
UIImage(named: "image2.png")!,
UIImage(named: "image3.png")!,
UIImage(named: "image4.png")!,
UIImage(named: "image5.png")!]
func anySimilarImages() {
// find first image which is the same as 1ImageView's
let 1ImageViewImage: UIImage? = imageArray.first { (image) -> Bool in
return image.pngData() == 1ImageView.image?.pngData()
}
// find first image which is the same as 2ImageView's
let 1ImageViewImage: UIImage? = imageArray.first { (image) -> Bool in
return image.pngData() == 2ImageView.image?.pngData()
}
if 1ImageViewImage != nil && 2ImageViewImage != nil {
print("both images were found")
}
else if 1ImageViewImage != nil {
print("first image was found")
}
else if 2ImageViewImage != nil {
print("second image was found")
}
else {
print("no image was found")
}
}

Setting UIImageView.image with valid UIImage creates "nil" error in swift

I am trying to set the image property on a UIImageView. When I use a UIImage to set the .image property it throws this error every time:
"unexpectedly found nil while unwrapping an Optional value"
The problem is that my UIImage is not nil.
Here is the code where I am setting the UIImage
func setPhotosForNewsItem(photoArray:[Photo]) {
println("Image Count: " + String(photoArray.count))
var image:UIImage = photoArray[0].photo
println(image.description)
self.newsImage.image = image
}
Here is the console output:
Image Count: 2
UIImage: 0x7fdd93c5cdd0, {1115, 1115}
fatal error:
unexpectedly found nil while unwrapping an Optional value (lldb)
I am able to use the Quick Look tool in xCode on my supposedly nil UIImage and see the photo that I am trying to use. Why would I be throwing a nil error when my UIImage is clearly not nil?
UPDATE::
It seems that I am not properly storing the UIImage in my array. Here is where I download my images and store them to my array for unpacking later.
var relatedPhotos:[PFObject] = relations as! [PFObject]
//println(relations!)
var photoArray:[Photo] = [Photo]()
for photo in relatedPhotos {
var newPhoto = Photo()
var photoFile:PFFile = photo.objectForKey("photo") as! PFFile
newPhoto.object = photo
newPhoto.objectID = photo.objectId!
photoFile.getDataInBackgroundWithBlock({(imageData: NSData?, error: NSError?) -> Void in
if (error == nil) {
newPhoto.photo = UIImage(data:imageData!)!
//println(newPhoto.photo)
photoArray.append(newPhoto)
if photoArray.count == relatedPhotos.count {
if newObject is FieldReport {
var report = newObject as! FieldReport
report.photos = photoArray
updatedReports.append(report)
//println("Report Count 1: " + String(updatedReports.count))
}
else {
var report = newObject as! Feature
report.photos = photoArray
updatedReports.append(report)
}
if updatedReports.count == objects.count {
self.delegate?.fieldReports(updatedReports)
}
}
}
})
}
I know that this works to download and display the photo as I have just used it successfully to do so. To me that means I am not storing the UIImage properly. Is there a different way I should be storing these image files?
You can prevent the crash from happening by safely unwrapping
func setPhotosForNewsItem(photoArray:[Photo]) {
println("Image Count: " + String(photoArray.count))
if var image:UIImage = photoArray[0].photo
{
println(image.description)
self.newsImage.image = image
}
}
Setup breakpoint and check what's wrong
EDIT:
The only thing i can purpose - check what happens here:
newPhoto.photo = UIImage(data:imageData!)!
seems like it's the main reason of all problems. check type of imageData, try to convert it to image via, for example UIImage(CGImage: <#CGImage!#>). You need to figure out how to deal with this image.

Check if string name matches an asset in images.xcassets

Everything I google turns up answers about ALAsset's.
I have an images.xcassets folder and a bunch of assets in there.
I want to know if an asset exists in there based on a string.
E.g. if(images.xcassets.contains("assetName") == true)
Do you know how I can check if an asset exists based on a string?
This is one way to check it.
NSString *someString = #"SomeStringFromSomwhere";
if ([UIImage imageNamed: someString])
{
//the image exists..
}
else
{
//no image with that name
}
Just a bit more practical answer: Swift
if let myImage = UIImage(named: "assetName") {
// use your image (myImage), it exists!
}
Check whether image exist or not : Swift 3
if (UIImage(named: "your_Image_name") != nil) {
print("Image existing")
}
else {
print("Image is not existing")
}
I ended up with some combination of both and turned it into a function to use throughout my code. I also want to return a default image if the one provided is missing. (Swift 4 version)
func loadImage (named: String) -> UIImage {
if let confirmedImage = UIImage(named: named) {
return confirmedImage
} else {
return UIImage(named: "Default_Image.png")
}
}
Then to load the image into something like a button you do something like this.
buttonOne.setImage(loadImage(named: "YourImage.png"), for: .normal)
For Swift, this is what I ended up using to assign either an existing asset or a default system image:
myImageView.image = UIImage(named: "myAssetName") ?? UIImage(systemName: "photo")
// When former is nil, assigns default system image called "photo"

How can I avoid the Optional.None error in this scenario?

var image = self.imageData[index] as NSString
if let derp = image as NSString? {
println(" \(image)")
} else {
println("is nil")
}
dataViewController.dataImage.image = UIImage(named: image) as UIImage
That last line:
dataViewController.dataImage.image = UIImage(named: image) as UIImage
gives me "Can't unwrap Optional.None", despite the image object successfully passing the optional binding test as shown here https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_428 . The image string does print at the bottom of Xcode.
It is possible you are getting that error because an image with that name does not exist. However, you also have some issues with your optional binding.
Optional binding is different from casting. You don't provide a new type. Also, even if casting was the way to do it, you are casting to an optional, which doesn't prove that image is not nil.
You have already asserted to the compiler that image is not nil with your as NSString on the first line. If this conversion is not successful at runtime, your whole app will crash.
After binding an optional, you should use the local variable, not use the optional later
This means your code should look like this:
var possibleImageName = self.imageData[index] as? NSString
if let imageName = possibleImageName {
var possibleImage : UIImage? = UIImage(named: imageName)
if let image = possibleImage {
dataViewController.dataImage.image = image
}
} else {
println("is nil")
}
After you understand the optional binding process, and the difference from casting, you can shorten the code to this:
if let imageName = self.imageData[index] as? NSString {
if let image = UIImage(named: imageName) as UIImage? {
dataViewController.dataImage.image = image
}
} else {
println("is nil")
}
Note: The check for nil from initializers is strange. You have to cast it to be an optional type so that you can actually test it because initializers from Objective-C actually return Implicitly Unwrapped Optionals.
UIImage(named:) may return nil in case the image with given name cannot be found. You need to check it did not nil.
var img : UIImage? = UIImage(named: image)
if img != nil {
dataViewController.dataImage.image = img!
}
or
if let img = UIImage(named: image) as UIImage! {
dataViewController.dataImage.image = img
}

Resources