I have a fatal error while unwrapping an optional value in swift.
I have a profile ViewController with a background image and an avatar image witch are the same.
When the user has not an image set, i ve got this fatal error, instead i would like to add a "by default image Shape".
How could i check if image isn't nil ?
This is my code :
var currentUser = PFUser.currentUser()
let User = currentUser as PFUser
let userImage:PFFile = User["profileImage"] as PFFile {
userImage.getDataInBackgroundWithBlock{(imageData:NSData!, error:NSError!)-> Void in
if !(error != nil) {
var image:UIImage! = UIImage(data: imageData)
if image != 0 {
self.backgroundImageUser.image = image
self.avatarUserView.image = image
}
else if image == 0 {
self.backgroundImageUser.image = UIImage(named: "Shape")
self.avatarUserView.image = UIImage(named: "Shape")
}
}}}
Try this:
userImage.getDataInBackgroundWithBlock{(imageData:NSData?, error:NSError?)-> Void in
if let image = UIImage(data: imageData) {
self.backgroundImageUser.image = image
self.avatarUserView.image = image
}
else {
self.backgroundImageUser.image = UIImage(named: "Shape")
self.avatarUserView.image = UIImage(named: "Shape")
}
}
let image : UIImage? = img
if image != nil{
}else{
}
In order to get this working, you have to understand Optional Chaining.
As the Apple Documentation says:
Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.
So if you want an object to get a nil Value, you have to declare it as Optional. To declare the object as Optional You have to place a question mark after the value.
In your example it will look just like this:
var image:UIImage? ;
image = UIImage(data: imageData) ;
And by declaring this UIImage as Optional, it will be initialized with nil.
swift 5
var imageBottom = UIImage.init(named: "contactUs")
if imageBottom != nil {
imageBottom = imageBottom?.withRenderingMode(.alwaysTemplate)
bottomImageview.image = imageBottom
}
In fact the problem was up, as you can see in the edited post, i had a the userImage declaration not optional.
So now everything work fine with :
var currentUser = PFUser.currentUser()
let User = currentUser as PFUser
if let userImage:PFFile = User["profileImage"] as? PFFile {
userImage.getDataInBackgroundWithBlock{(imageData:NSData!, error:NSError!)-> Void in
if !(error != nil) {
var image :UIImage! = UIImage(data: imageData)
self.backgroundImageUser.image = image
self.avatarUserView.image = image
}
}}
else {
self.backgroundImageUser.image = UIImage(named: "Shape")
self.avatarUserView.image = UIImage(named: "Shape")
}
Related
I'm trying to encode UIImage as base64 string. My code is this:
#IBOutlet weak var photoImageView: UIImageView!
let image : UIImage = UIImage(named:"photoImageView")!
let imageData:NSData = UIImagePNGRepresentation(image)!
let strBase64:String = imageData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
the problem is that I get this kind of error : "fatal error: unexpectedly found nil while unwrapping an Optional value"
What am I doing wrong?
Prasad's comment is likely the issue you're running into.
For any functions that return optionals, I usually use if - let syntax or guards to make sure I don't accidentally unwrap a nil.
if let image = UIImage(named:"photoImageView") {
if let imageData = UIImagePNGRepresentation(image) {
// swift 2
// imageData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
// swift 3
let strBase64:String = imageData.base64EncodedString(options: [.lineLength64Characters])
} else {
print("can't get PNG representation")
}
} else {
print("can't find photoImageView image file")
}
#Enix your comment did the trick. Solution to my problem was this line
let image = photoImageView.image
As you have pointed out UIImage is initialised with image asset, not with an image view
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
There is some problem with AddressBook which I can't reproduce, code works on my iPhone and iPad, this happens on client phone and result in app crash. As far as I can see from Crashlytics problem should be in following line:
let data = ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail).takeRetainedValue()
Here is complete code for reading address book:
var err : Unmanaged<CFError>? = nil
let addressBookRef : ABAddressBook? = ABAddressBookCreateWithOptions(nil, &err).takeRetainedValue()
if addressBookRef == nil {
print(err)
return
}
let contacts = ABAddressBookCopyArrayOfAllPeople(addressBookRef).takeRetainedValue() as NSArray as [ABRecord]
for contact in contacts {
let firstName = ABRecordCopyValue(contact, kABPersonFirstNameProperty)?.takeRetainedValue() as? String
let lastName = ABRecordCopyValue(contact, kABPersonLastNameProperty)?.takeRetainedValue() as? String
var image: UIImage?
if ABPersonHasImageData(contact) {
let data = ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail).takeRetainedValue()
if let img = UIImage(data: data) {
image = img
}
}
…
}
Do you have any suggestions what could happen on clients phone so I can reproduce this error? Is it possible that some contact is corrupt? How should I handle this?
I've seen this post Get iOS contact image with ABPersonCopyImageData that ABPersonCopyImageData could return nil, I tried to handle that but app is still crashing.
check all for nil. if ABPersonCopyImageDataWithFormat returns nil, you call takeRetainedValue on nil. and then use it nil to create image too
guard let CFData = ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail) else {
print("no cfdata")
return
}
if let data = CFData.takeRetainedValue {
if let img = UIImage(data: data) {
image = img
}
}
Maybe you should test the data itself and not the UIImage and also initialize an UIImageView instead of a UIImage.
if let data = ABPersonCopyImageDataWithFormat(contact, kABPersonImageFormatThumbnail).takeRetainedValue()
image = UIImage(data: data)
}
In my ViewController, a user has the option to have an image as his/her background, stored in Parse. HOWEVER, when I delete this file, I get the following error - fatal error: unexpectedly found nil while unwrapping an optional value. I have an if statement nested within an if statement nested within an NSData fetch:
// Load userBackground IF they have one. ELSE: keep it default
let RPUserBackground = currentRPUser!["userBackground"] as? PFFile
RPUserBackground!.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
// If there is NO ERROR (nil)
// Set userProfilePicture
if let imageData = imageData {
// If let statements hold an optional value
// IF imageData == imageData, set userProfilePicture
// THIS MEANS THAT THE OPTIONAL IS NOT NIL
self.RPUserBackground.image = UIImage(data: imageData)
self.RPDefaultView.hidden = true
self.RPUserBiography.textColor = UIColor.whiteColor()
}
} else {
// If there is an error, set default
self.RPUserBackground.hidden = true
self.RPUserBiography.textColor = UIColor.grayColor() // GET RBG COLOR LATER
self.RPDefaultView.hidden = false
}
}
I don't know where this is coming from. I know that an if let statement returns an optional so I tried executing code to that relative if statement with an else. I don't know what's going on, please help me catch the error!
if let RPUserBackground = currentRPUser!["userBackground"] as? PFFile {
RPUserBackground.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
// Set user's background Photo
if let imageData = imageData {
/*
let image = UIImage(data: imageData)
let size = CGSize(width: image!.size.width / 2, height: image!.size.height / 2)
self.RPUserProPic.image = image
self.RPUserProPic.contentMode = .ScaleAspectFit
*/
self.RPUserBackground.image = UIImage(data: imageData)
self.RPDefaultView.hidden = true
self.RPUserBiography.textColor = UIColor.whiteColor()
}
}
}
} else {
print("User does not have a preferred background photo")
self.RPUserBackground.hidden = true
self.RPUserBiography.textColor = UIColor.grayColor() // GET RBG COLOR LATER
self.RPDefaultView.hidden = false
}
Im storing an NSURL for a Facebook profile picture that looks like "http://graph.facebook.com/(id)/picture?type=large" where id is the user's id.
I want to display the image from that url in a UIImage
I am trying to do this like so:
var data = NSData(contentsOfURL: profilePictureURL)
cell.backgroundImage = UIImage(data: data)
But XCode throws an error on that second line that says:
"Missing argument for parameter 'inBundle' in call" but obviously that's not a parameter in this call. I even tried adding it once before and once after like UIImage(data: data, inBundle: nil) and reversed but it said "extra argument inBundle"
Help please!
**** EDIT ****
Found the problem:
cell.backgroundImage = UIImage(data: data)
should be
cell.backgroundImage.image = UIImage(data: data)
As you note, you want to set the image property of cell.backgroundImage. Also, you will want to unwrap that optional.
You can do a forced unwrapping:
let data = NSData(contentsOfURL: profilePictureURL)
cell.backgroundImage.image = UIImage(data: data!)
Or, a little safer, and optional binding:
if let data = NSData(contentsOfURL: profilePictureURL) {
cell.backgroundImage.image = UIImage(data: data)
}
And, if you want to be especially prudent, and do this asynchronously, it would look like:
cell.backgroundImage.image = nil // initialize it to nil before we go to get image asynchronously
NSURLSession.sharedSession().dataTaskWithURL(profilePictureURL) { data, response, error in
if data == nil {
println("dataTaskWithURL error: \(error)")
} else {
if let image = UIImage(data: data) {
dispatch_async(dispatch_get_main_queue()) {
cell.backgroundImage.image = image
}
}
}
}