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...
Related
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)
ok guys can I get a little help with my code. When running the app I get an error is there any way to fix this problem?
let fileUrl = dict["fileUrl"]as! String
let url = NSURL(string: fileUrl)
let data = NSData(contentsOf: url! as URL!)
let picture = UIImage(data: data! as Data!)
let photo = JSQPhotoMediaItem(image: picture)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
Image here
Here I see 4 big fat problems with your code.
You are force casting the value of fileUrl of the dictionary dict to String. If your dictionary doesn't have the value for fileUrl, or if it's not castable to string, your code will crash. You should change that to optional cast like:
if let fileUrl = dict["fileUrl"] as? String
{
//your code if you have fileUrl
}
When creating the url to the file, you are using the wrong initialization method, you should be using this:
let url = URL(fileURLWithPath: fileUrl)
After you have the url to the file, you should also check if you have the data of the file, because contentsOfFile: initializer of the NSData returns the optional object, which may be nil, so another if check:
if let data = NSData(contentsOf: url) {\\ code with the data}
init?(data: Data) initializer of the UIImage also returns optional object, so if the required by latter code, you should also check if you have the image or nil with if statement.
The result code should be something like:
if let fileUrl = dict["fileUrl"] as? String {
let url = URL(fileURLWithPath: fileUrl)
if let data = NSData(contentsOf: url) {
let image = UIImage(data: data as Data) // you can cast NSData to Data without force or optional casting
let photo = JSQPhotoMediaItem(image: image)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
}
}
Hope this helps.
Replace the first line of code with this line for optional binding check :-
guard let fileUrl = dict["fileUrl"] as! String else {return}
Yo should do validation in cases where the variable may be nil, the following is an example:
if let fileUrl = dict["fileUrl"] as? String {
let url = URL(string: fileUrl)
do {
let data = try Data(contentsOf: url!)
let picture = UIImage(data: data)
let photo = JSQPhotoMediaItem(image: picture)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
} catch {
}
}
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()
Looking through the forums I have found that this issue is one that shows its head every now and then. And apparently doing so in a wide scope of different cases. None that I have managed to find seem to be similar to mine though.
I'm halfway through my program (lesson) in creating a usable twitter application. Testing it currently runs the program as it should, without any errors. But when I select an account the program crashes and an error message shows up at the image method which is supposed to load the avatar of the selected user. I assume that it is not able to retrieve a valid image or fetch data at all (because of the line ImageData = (NSDATA?) nil in the debug area), but I am by no means sure of anything, let alone how to or where to find a solution. If I am searching with the wrong keywords then please let me know. (I am searching for exc_bad_instruction and uiimage error) Thanks in advance.
I'll post the snippet of code where the issue presents itself below and what is shown in the debug area below that.
if let cachedImage = image {
cell.tweetUserAvatar.image = cachedImage
}
else {
cell.tweetUserAvatar.image = UIImage(named: "camera.png")
queue?.addOperationWithBlock() {
let imageURL = NSURL(string: imageURLString) as NSURL!
let imageData = NSData(contentsOfURL: imageURL) as NSData?
let image = UIImage(data: imageData!) as UIImage? // EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subode=0x0)
if let downloadedImage = image {
NSOperationQueue.mainQueue().addOperationWithBlock(){
let cell = tableView.cellForRowAtIndexPath(indexPath) as! TweetCell
cell.tweetUserAvatar.image = downloadedImage
}
self.imageCache?.setObject(downloadedImage, forKey: imageURLString)
}
}
}
Debug area:
imageURLString String
"http://pbs.twimg.com/profile_images/465756113825067008/8jH2nZO0_normal.png"
tableView UITableView 0x00007fc52481b400
indexPath NSIndexPath * 0xc000000000000016
self Chapter7_8___Social_App.FeedViewController 0x00007fc5235f5ef0
imageURL NSURL! "http://pbs.twimg.com/profile_images/465756113825067008/8jH2nZO0_normal.png"
imageData NSData? nil None
image UIImage? 0x000000010ee778dd
downloadedImage UIImage
I had this issue as well and found that my image was being initialized with bad data. This is to say that the image I requested from the server did not exist and the server sent back a response which could not be converted into an UIImage.
To mitigate this you can do the following:
if let cachedImage = image {
cell.tweetUserAvatar.image = cachedImage
}
else {
cell.tweetUserAvatar.image = UIImage(named: "camera.png")
queue?.addOperationWithBlock() {
let imageURL = NSURL(string: imageURLString) as NSURL!
let imageData = NSData(contentsOfURL: imageURL) as NSData?
if let image = UIImage(data: imageData!) {
let downloadedImage = image
NSOperationQueue.mainQueue().addOperationWithBlock(){
let cell = tableView.cellForRowAtIndexPath(indexPath) as! TweetCell
cell.tweetUserAvatar.image = downloadedImage
}
self.imageCache?.setObject(downloadedImage, forKey: imageURLString)
}
}
}
What I have done above is changed
let image = UIImage(data: imageData!) as UIImage?
if let downloadedImage = image {
...
...
}
To:
if let image = UIImage(data: imageData!) {
let downloadedImage = image
...
...
}
In this way I have checked that the image was able to be created successfully. If the image is not able to be created then the code will not execute and you will not receive an error.
If you expect an image to be at the url you specified in 'imageURLString' then I would suggest that you check the url you are using.
I also noticed that you did not get any data back which is why you could not create the UIIMage. You can test to see if this is the case with the following:
let imageData = NSData(contentsOfURL: imageURL) as NSData?
if imageData != nil {
Do More Stuff
...
{
I hope my answer was helpful. If you have any questions feel free to leave a comment and I'll do my best to answer them.
More Info Here:
This question & answer also provides methods on how to handle the case when the UIImage cannot be created from the data provide.
I'm trying to display image to imageView from URL. I successfully done it using synchronous method in a simple project. But this application is used for online store, so I took product information and image URL from a JSON file. which I'm sure I was successfully stored all the data in a product array. But the problem I'm facing is this:
fatal error: unexpectedly found nil while unwrapping an Optional value
Here is the code.
// UnWrapping imageURL
let url:NSURL? = NSURL(string: actualCurrentProduct.imageURL)
if let actualURL = url {
let imageData = NSData(contentsOfURL: actualURL)
if let actualImageData = imageData {
self.productImageView.image = UIImage(data: actualImageData)
}
}
It highlighted in this particular code.
self.productImageView.image = UIImage(data: actualImageData)
Anybody have any idea why? Really appreciated it.
I managed to display the image successfully from URL with this code. I started the project from the scratch and for the display image part, here is my code.
let imageURL = NSURL(string: actualCurrentProduct.imageURL)
if let actualImageURL = imageURL {
let imageData = NSData(contentsOfURL: actualImageURL)
if let actualImageData = imageData {
let image = UIImage(data: actualImageData)
if let actualImage = image {
self.productImage.image = actualImage
}
}
}
Finally....