Fatal Error: Unexpectedly found nil while unwrapping an Optional value NSURL - ios

I getting nil error. But I didnt understand why happaned. I can get selectedPhoto name with print. But I cant use in NSUrl. Could you help me pls?
my codes:
print(selectedPhoto)
if selectedPhoto != nil
{
let photoUrl = NSURL(string: "http://www.kerimcaglar.com/uploads/yemek-resimler/\(selectedPhoto)")
print("photo url: \(photoUrl)")
dataPhoto = NSData(contentsOfURL:photoUrl!)
yemekResim.image = UIImage(data: dataPhoto!)
}
else
{
print("Error")
}

From Apples documentation on NSData(contentsOfURL)
Do not use this synchronous method to request network-based URLs. For network-based URLs, this method can block the current thread for tens of seconds on a slow network, resulting in a poor user experience, and in iOS, may cause your app to be terminated.
If your app crashes because of this it will be rejected from the store.
Instead you should use NSURLSession. With the Async callback block as in my example.
Also it is not a good idea to force unwrap optionals ! as you will get run time errors instead use the if let syntax
See my example below.
if let photo = selectedPhoto{
let photoUrl = NSURL(string: "http://www.kerimcaglar.com/uploads/yemek-resimler/\(photo)")
if let url = photoUrl{
NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: {(data, response, error) in
if let d = data{
dispatch_async(dispatch_get_main_queue(), {
if let image = UIImage(data: d) {
self.yemekResim.image = image
}
})
}
}).resume()
}
}
}

Replace this:
let photoUrl = NSURL(string: "http://www.kerimcaglar.com/uploads/yemek-resimler/\(selectedPhoto)")
with this:
let photoUrl = NSURL(string: "http://www.kerimcaglar.com/uploads/yemek-resimler/\(selectedPhoto!)")
(Notice the "!" after selectedPhoto)

Related

how to load an image from the url getting from server

I am having and imageView and I am getting the userData from the server when loggedIn in the userData I have a parameter for "profilePic":"penguins.jpg". now I am adding the domain like "http://.....(self.userData.value(forKey: "profilePic")!)" and saving this value into a string variable to store and when I am accessing the value and trying to convert the url into data and adding to imageView.image it is throwing : unexpectedly found nil while unwrapping an optional value..
All my other userData like name,address,phoneNumber are showing fine except for Image.
My Code:
here are the some of the many ways I tried:
way:1
let ad : AppDelegate = UIApplication.shared.delegate as! AppDelegate
let imageUrlString = ad.userImagePath
let imageUrl:URL = URL(string: imageUrlString)! // it is throwing error here(: unexpectedly found nil while unwrapping an optional value)
DispatchQueue.global(qos: .userInitiated).async {
let imageData:NSData = NSData(contentsOf: imageUrl)!
DispatchQueue.main.async {
let image = UIImage(data: imageData as Data)
self.profileImage.image = image
}
}
way:2
if let url = NSURL(string: ad.userImagePath) {
if let data = NSData(contentsOf: url as URL){
if let imageUrl = UIImage(data: data as Data) {
profileImage.image = imageUrl
}
}
}
I have tried different ways to solve this, can't figure out what is my mistake.. finally I am here.. Please someone help he...

Firebase reference is 'variable not available' when downloading picture in Swift

Title says everything. I'm just unable to download an image from Firebase Storage dir. Here is the snippet of the code which calls the function for setting data and it also calls the function which tries to download the picture:
for element in Dict {
if let itemDict = element.value as? [String:AnyObject]{
let name = itemDict["name"] as! String
let price = itemDict["price"] as! Float
let imageObject = itemDict["image"] as! NSDictionary
let hash = imageObject["hash"] as! String
let storageDir = imageObject["storageDir"] as! String
let image:UIImage = self.downloadImageProductFromFirebase(append: hash)!
let product = Product(name: name, image: image, imageName:hash, price: price, storageDir : storageDir)
self.productList.append(product)
}
}
print(Dict)
self.myTable.reloadData()
And here is the code which tries to download the image:
func downloadImageProductFromFirebase(append:String) -> UIImage?{
let gsReference = Storage.storage().reference(forURL: "gs://fridgeapp-3e2c6.appspot.com/productImages/productImages/" + append)
var image : UIImage?
gsReference.downloadURL(completion: { (url, error) in
if error != nil {
print(error.debugDescription)
return
}
URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
if error != nil {
print(error.debugDescription)
return
}
guard let imageData = UIImage(data: data!) else { return }
DispatchQueue.main.async {
image = imageData
}
}).resume()
})
return image
}
But, for some reason, it crashes just when calling this last function, saying that "fatal error: unexpectedly found nil while unwrapping an Optional value". I tried to use the debugger, and I found out that Firebase reference to Storage variable says "variable not available".
Could someone of you guys help me with this? I think I read the Firebase doc about a hundred times, and still can't get the point.
Thank you!
Downloading an image from a remote server is an asynchronous task, that means that the result is not immediately available. This is the reason that gsReference.downloadURL accepts a completion callback as an argument, and has no return value.
Since your function (downloadImageProductFromFirebase) is simply a wrapper to gsReference.downloadURL, it should also accept a completion callback as an argument, and should not have a return value (i.e. remove the -> UIImage?).
When you call self.downloadImageProductFromFirebase pass in a closure that receives the image, finds the index of the corresponding product in productList, and sets itself as the cell's image (assuming you're showing the image in the cell).
See this answer for how to asynchronously set cell images.

NSData contentsOfURL Returns Nil?

I have the following code
import Foundation
let url = NSURL(string: copiedURL)
let data = NSData(contentsOfURL: url!)
print("\(data)")
let image2 = UIImage(data: data!)
When I build and run, I get the following error fatal error: unexpectedly found nil while unwrapping an Optional value referring to
let image2 = UIImage(data: data!)
I tried to modify my Info.plist with the following
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
But the error is still there. Is there any more possible solutions I can try?
Couple of possibilities here.
The copiedURL is not being properly converted to a NSURL
The NSURL is not being converted to NSData
The image is unable to load the data
Try the following:
if let url = NSURL(string: copiedURL) {
print(url)
if let data = NSData(contentsOfURL: url) {
print(data)
let image2 = UIImage(data: data)
}
}
It's almost never a good idea to force unwrap something (!), instead use guard or if let to unwrap and thus be able to handle the nil condition.
Refer to: Loading/Downloading image from URL on Swift for how to properly download images.
Try the following code:
if let url = NSURL(string: copiedURL) {
if let data = NSData(contentsOfURL: url) {
print("\(data)")
let image2 = UIImage(data: data)
}
}
If copiedURL has valid image you will get it, otherwise atleast your app will not crash.

Swift 2.0 fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)

let imgURL:NSURL = NSURL(string: "\(ImageName)")!
at the above line,i'm getting fatal error
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
Code :
let ImageName = obj["image"] as! String
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
Imgtask.resume()
From the above code im trying to store my image from database in annotation
if i printed the 'ImageName' it returns the name from the database correctly, but unable to retain the image
it resulting in the error while running.
You say that
if i printed the 'ImageName' it returns the name from the database correctly
Then that must mean that the ImageName is not valid for a URL
If you look at the description of NSURL(string:) it says:
The URL string with which to initialize the NSURL object. This URL string must conform to URL format as described in RFC 2396, and must not be nil. This method parses URLString according to RFCs 1738 and 1808.
So the question is...how does ImageName look? And can you create a URL from it?
Apart from that, it is always a good idea to use ? instead of ! as #PhillipMills says
Update: I can see that you have posted an example of your URL now. If I do this in a playground:
let url = NSURL(string: " goo.gl/pBmA0d")
I get nil in return, so it would seem that short URLs and NSURLaren't the best of friends.
Update 2: hmm, guess I spoke to quickly, if you look at the above you can see that I have a space before the goo.gl part, if I change that to:
let url = NSURL(string: "goo.gl/pBmA0d")
it actually works, I get a NSURL object.
But another thing I stumbled upon in your code. You declare ImageName as a String here:
let ImageName = obj["image"] as! String
So you don't have to wrap it in \() later on
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
You could simply say:
let imageURL = NSURL(string: ImageName)
And then...as others has said, it is always a good idea to use ? instead of !
So you could write:
if let imageName = obj["image"] as? String,
let imageURL = NSURL(string: imageName) {
//we're in business :-)
}
and be safe and sound
Try to use guard or if let for helping yourself.
let ImageName = obj["image"] as! String
if let imgURL = NSURL(string: ImageName) {
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){ (data, response, error) -> Void in
if (error == nil && data != nil)
{
// What's that func??
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
}
Imgtask.resume()
Don't make force unwrap...use if let to avoid crash ...
if let img = obj["image"] as? String,
imgURL = NSURL(string: img) {
// ... continue with your code ...
}
Please try the following code:
//ImageName is a String type.
guard let ImageName = obj["image"] as? String , let imgURL = NSURL(string: ImageName) else{
return
}
let request: NSURLRequest = NSURLRequest(URL:imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
Imgtask.resume()

UIImage Download Returning nil and Crashing App (Swift)

I have an image url string:
var remoteImage: String = "http://server.com/wall-e.jpg"
I then construct a UIImage to download on a separate thread using Grand Central Dispatch with remoteImage as the NSURL string parameter:
let getImage = UIImage(data: NSData(contentsOfURL: NSURL(string: remoteImage)!)!)
When it is finished and I return back to the main thread, I have it save internally:
UIImageJPEGRepresentation(getImage, 1.0).writeToFile(imagePath, atomically: true)
On Wi-fi and LTE it downloads fine, but when testing edge cases such as on an Edge network (no pun intended), I inconsistently get the error:
fatal error: unexpectedly found nil while unwrapping an Optional value
Now I thought I would be safe by making sure that it wasn't nil by adding in:
if getImage != nil { ... }
But it didn't seem to make a difference. It still gets the error and highlights the let getImage as written above. What am I doing wrong here? Should I be checking nil in a different manner or method?
I would recommend you to use AsyncRequest to fetch and download the image and saved it locally.
As you didn't posted any of code of your problem.
So i am posting a sample working for me.
Sample for downloading and saving image locally
var url = NSURL(string : "http://freedwallpaper.com/wp-content/uploads/2014/09/Tattoo-Girl.jpg")
let urlrequest = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(urlrequest, queue: NSOperationQueue.mainQueue(), completionHandler: {
response ,data , error in
if error != nil
{
println("error occurs")
}
else
{
let image = UIImage(data: data)
/* Storing image locally */
var documentsDirectory:String?
var paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
println(paths)
if paths.count > 0{
documentsDirectory = paths[0] as? String
var savePath = documentsDirectory! + "/bach.jpg"
NSFileManager.defaultManager().createFileAtPath(savePath, contents: data, attributes: nil)
self.bach.image = UIImage(named: savePath)
}
}
})
}
The error, does, in fact lie on the line:
let getImage = UIImage(data: NSData(contentsOfURL: NSURL(string: remoteImage)!)!)
The reason is that it's not the UIImage that is initially returning nil, it is probably NSData returning nil. You could check if NSData is returning nil, and then create the UIImage object instead.
EDIT: What the particular line of code is doing is it is assuming that NSData is always returning a non-nil value, which may not be true when you are not connected. When you're not connected, it gets a nil value, which you are trying to say will never be a nil value using the exclamation mark (!).
I suggest you read further on how Swift works. For this particular example, take a look at what the exclamation marks actually mean in Swift: What does an exclamation mark mean in the Swift language?

Resources