Found nil value in dictionary when it isn't nil - ios

I want to create URL from string in dictionary, but when I initialize it, the guard statement goes to else statement, because values["Image"] is nil and return the function. Here is a piece of my code
guard let imageURLInDatabase = URL(string: values["Image"]!) else { return }
let data = NSData(contentsOf: imageURLInDatabase)
I have create afew breakpoint in my code:
And here is my console log at this breakpoint:
What did I miss?
P.S
I tried to do it like:
let imageURLInDatabase = URL(string: values["Image"]!)
but I got error message unexpectedly found nil while unwrapping an optional value
Edit 1:
I tried to do it like
guard let imageString = values["Image"] else{return}
guard let imageURLInDatabase = URL(string: imageString) else{
return}
let data = NSData(contentsOf: imageURLInDatabase)
And set breakpoints:
So values["Image"] can't be nil
Edit 2:
This is what is in values["Image"]:
some : "https://firebasestorage.googleapis.com/v0/b/blackjack-ef580.appspot.com/o/profiles_images%2FdwMGR8sKMvYauf6uQDtyop18cwy1.jpg?alt=media&token=5df48794-d3fd-4e5c-a72c-9928a8a43c4e\""

The problem is the extra quotation mark at the end of the URL string. Try this:
let s = "https://firebasestorage.googleapis.com/v0/b/blackjack-ef580.appspot.com/o/profiles_images%2FdwMGR8sKMvYauf6uQDtyop18cwy1.jpg?alt=media&token=5df48794-d3fd-4e5c-a72c-9928a8a43c4e\""
let url = URL(string:s)
You'll get nil.

The problem isn't that values["Image"] is nil. The problem is that values["Image"] isn't a value URL string.
Make sure you properly encode spaces and other special characters in the URL.
And as a side note, do not use NSData, use Data.

According to your trace, the problem isn't that value["Image"] is nil. If that were the case, you would have crashed rather than called return. Your problem is that whatever the value of value["Image"], it is not a valid URL. Without seeing the value, it's difficult to know exactly what is wrong with it, but it is malformed in some way.

This is because the dictionary values does not contains the key Image. So values['Image'] will return nil, and force unwrapping a nil will crash the app.
Try using guard else statements to unwrap it
guard let imageValue = values["Image"] as? String else {
//imageValue is nil here, handle accordingly
return
}
guard let imageURLInDatabase = URL(string: imageValue) else {
//imageURLInDatabase is nil here, handle accordingly
return
}
let data = NSData(contentsOf: imageURLInDatabase)
Edit 1:
With your updated question, and the breakpoint image, values["Image"] is not null, imageURLInDatabase is nil due to which it goes to else case.
The reason could be that values["Image"] might not be returning a valid url, due to which URL(string: ..) fails.
Edit 2 :
Check the string url you just shared
"https://firebasestorage.googleapis.com/v0/b/blackjack-ef580.appspot.com/o/profiles_images%2FdwMGR8sKMvYauf6uQDtyop18cwy1.jpg?alt=media&token=5df48794-d3fd-4e5c-a72c-9928a8a43c4e\""
has an extra quote in the end!

Related

Thread 1: found nil [duplicate]

This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 4 years ago.
This question might be a duplicate, but I think my case is different.
I built an app to fetch news articles from different sources. The problem I have is some sources may not include article image which causing my app to crash, please have a look at my code:
extension UIImageView {
func downloadImage(from url: String) {
let urlRequest = URLRequest(url: URL(string: url)!) // I get Fatal error on this line
let task = URLSession.shared.dataTask(with: urlRequest) { (data,response,error) in
if error != nil {
print(error as Any)
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}
task.resume()
}
}
I tried to modify the code to not force unwrap the image if found nil, but It just didn't work, because I get other errors in other places.
If anyone can point the mistake, please, by writing how the code should be in case image found nil to not crash the app. It will be extremely appreciated!
The URL is force unwrapped. You should unwrap optional by using guard let construction:
guard let url = URL(string: url) else { return }
let urlRequest = URLRequest(url: url)
I tried to modify the code to not force unwrap the image if found nil,
Well yes it's duplicated question.
However this problem is solved by OptionalChaining i recommend reading about it Here,
Now for the part on how to solve it quickly, you can try to add this line under your request, which is going to check if its nil or not, and incase it was nil it will simply escape the closure without causing any crashes or problems.
guard let data = data else {return}
There are many types of OptionalChaining, each one has its own usage but they all serve the same propose of handling the nil values without causing a crashes.
DispatchQueue.main.async {
guard let data = data {
self.image = UIImage(data: data)
} else {
print(value is nil.)
}
}
This is the way to safe unwrap the optional value. It will not crash if Data is nil on unwrapping .

Kingfisher nil while unwrapping optional value

I have Medicine struct that holds image_origin URL of image I want to download and set to the ImageView.
For downloading/caching purposes I'm using Kingfisher framework.
let m = medicines[indexPath.row]
cell.medicineImage.kf.setImage(with: URL(string: m.value(forKeyPath: "image_origin") as! String)!)
cell.medicineName.text = m.value(forKeyPath: "i_name") as? String
In the code above m is an NSManagedObject of CoreData. I try to get image URI from the CoreData and set it to the ImageView, but every time at the line 2 I get the following error message: Unexpectedly found nil while unwrapping an Optional value
I have tried changing variables and Optinal types, tried to hardcode URI but without success.
What am I doing wrong?
P.S. Im using Swift4
Just unwrap safely to fix the crash and check your database if you are not getting the urlString properly,
if let urlString = m.value(forKeyPath: "image_origin") as? String {
print(urlString)
guard let url = URL(string: urlString) else { return }
cell.medicineImage.kf.setImage(with: url)
}
There might be a problem with image_origin key that I may have value as string or may not have. So, just need to confirm the value and use it
let m = medicines[indexPath.row]
cell.medicineName.text = m.value(forKeyPath: "i_name") as? String
guard let urlPath = m.value(forKeyPath: "image_origin") as? String, let url = URL(string: urlPath) else { return }
cell.medicineImage.kf.setImage(with: url)

Swift 3 error handling and variable accessibility

I have a question on how to use the new error handling in Swift.
I'm reading contents of a file into a data object:
var overallData: Data?
//load file contents into data object
let dataFileURL = NSURL(string: fileName)
do {
overallData = try Data(contentsOf: dataFileURL as! URL)
} catch {
print("\(error)")
}
The problem is that I always encounter this error message:
fatal error: unexpectedly found nil while unwrapping an Optional value
The problem is that the overallData object is set as nil. But if I don't define a data variable outside the do-catch,
let dataFileURL = NSURL(string: fileName)
do {
overallData = try Data(contentsOf: dataFileURL as! URL)
} catch {
print("\(error)")
}
Later on, I can't use the overallData object because the system keeps telling me it's a variable not defined yet. So it looks like new variables defined in the do-catch loop can only be locally accessed inside the loop.
Do you know how to solve this problem? I do need to use the overallData object elsewhere.
The following answer assumes your error is with the line:
overallData = try Data(contentsOf: dataFileURL as! URL)
If you are getting the "fatal error" on another line, please update your question.
Your error has nothing to do with the do/catch/try.
Your problem is the force unwrapping of dataFileURL which is nil.
Your problem is this line:
let dataFileURL = NSURL(string: fileName)
This is returning nil because fileName isn't a valid URL.
Assuming fileName is a path to a local file, you need to do:
let dataFileURL = URL(fileURLWithPath: fileName)
Also note the use of URL instead of NSURL. There is no sense in using NSURL in Swift 3.

Object is nil but code interpret not as nil

I want to check if an object I get from the server is nil or not, if nil I want to use a placeholder image, if not nil I want to use the image from the url. Debugger says imageUrl is nil, but my code evaluates it as not nil.
the code always crash at
providerImg.sd_setImageWithURL(NSURL(string: GPProfiles[indexPath.row]["image"] as! String))
I have also tried this
let imageUrl = GPProfiles[indexPath.row]["image"]
if imageUrl != nil {
providerImg.sd_setImageWithURL(NSURL(string: GPProfiles[indexPath.row]["image"] as! String))
} else{
providerImg.image = UIImage(named: "placeholderImage.png")
}
How can I check if an object is nil ??? Thanks
UPDATE TO ANSVWER BY #andre-slotta
try this:
if let imageUrl = GPProfiles[indexPath.row]["image"] as? String {
...
}
since your != nil check does not seem to work here you get some more info about nil, NULL and NSNull: nshipster.com/nil

Check if url image exist

I'm trying to check if a url image exist using a if statement. However when trying to test it by wrong image url it keep returning:
fatal error: unexpectedly found nil while unwrapping an Optional value.
code:
var httpUrl = subJson["image_url"].stringValue
let url = NSURL(string: httpUrl)
let data = NSData(contentsOfURL: url!)
if UIImage(data: data!) != nil {
}
You can do it this way:
var httpUrl = subJson["image_url"].stringValue
if let data = NSData(contentsOfURL: url) {
//assign your image here
}
Other answers are telling you to unwrap the optional, but really the issue is that you are force-unwrapping the optional with !, despite it being nil.
When you write something! what you are saying is “something might be nil, but if it is, I want my program to crash”.
The reason a call might return nil is if the result is not valid – for example, if you try to fetch a key from a dictionary that isn’t there, or that a URL doesn’t point to a valid downloadable image.
You can combine the check for nil with an if statement that unwraps the optional and returns a non-optional value so long as the value wasn’t nil. You can also chain them together, so if you need to unwrap a value, then pass it into a call that also returns an optional, you can do it all in one if statement:
if let httpUrl = subJson["image_url"].string,
url = NSURL(string: httpUrl),
data = NSData(contentsOfURL: url),
image = UIImage(data: data)
{
// use image value
}
else {
// log some error
}
Note, on the first line, the call is to .string rather than .stringValue – .string also returns an optional with nil if the value isn’t present.
Of course, combining all these unwraps together means you can’t tell which one failed, so you may want to break them out into separate statements instead.
This code is tested and successful: if image url not exists no crash.
let url: NSURL = NSURL(string: "http://www.example.com/images/image.png")!
do {
let imgData = try NSData(contentsOfURL: url, options: NSDataReadingOptions())
ImageView?.image = UIImage(data: imgData)
} catch {
print(error)
}
You have to unwrap the optional like this:
if let image = data {
// use image here
} else {
// the data is nil
}

Resources