I am parsing JSON data. After I start getting unexpectedly found nil while unwrapping an Optional value errors. I tried to use guard statement.
But again I am getting the same error.
guard let articleTitle = self.articles?[indexPath.row]["title"].string! else {return}
I simulate nil value like this:
guard let articleTitle = self.articles?[indexPath.row]["t"].string! else {return}
What I am doing wrong?
It doesn’t make much sense to force unwrap the optional in a conditional let assingment. Remove the !:
guard let articleTitle = self.articles?[indexPath.row]["title"].string else {return}
Otherwise the right-hand side will never produce nil but crash.
Related
I'm confused about using UIGraphicsGetImageFromCurrentImageContext() in Swift, making me force unwrap it, even though it is defined with let. Adding in the ? or ! is making my code look messy and making me change everything after it. I'd like to not require this when defining scaledImage.
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let scaledCIImage:CIImage = (scaledImage?.ciImage)! // makes me force upwrap
// gives error 'Value of optional type 'CIFilter?' not unwrapped; did you mean to use '!' or '?'?'
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]).outputImage
There are plenty of legitimate uses of ! if you know when to use it properly.
From the documentation for UIGraphicsGetImageFromCurrentImageContext:
If the current context is nil or was not created by a call to UIGraphicsBeginImageContext(_:), this function returns nil.
Since you are using UIGraphicsBeginImageContext and your current context isn't nil, then UIGraphicsGetImageFromCurrentImageContext() won't return a nil so it is safe to force-unwrap.
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()!
As for creating the CIImage, the CIFilter, and the file CIImage, safely unwrap using if let.
if let scaledCIImage = scaledImage.ciImage,
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]),
let outputImage = filter.outputImage {
// Do what you need with outputImage
}
Update based on your comments:
Given that scaledmage.ciImage is nil and you want to try to create a CIImage from the cgImage, you can update the chain of if let to:
if let cgImage = scaledImage.cgImage {
let scaledCIImage = CIImage(cgImage: cgImage)
if let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]),
let outputImage = filter.outputImage {
// Do what you need with outputImage
}
}
Adding in the ? or ! is making my code look messy and making me change everything after it.
Well, whether it's messy is quite subjective. Swift is designed this way to make you think about each optional you unwrap carefully. By doing this, you can avoid lots of those "unexpectedly found nil while unwrapping an optional value" errors.
Methods and properties return nil for a reason. Usually the reason is that an error occurred, the thing couldn't be done, or there is no valid value for a property. You should think about these problems - "what should my method do if this method returns nil?"
If you want to do something else when the value is nil (i.e. it being nil is not fatal to your logic), use a if let statement. e.g.
if let scaledCIImage = scaledImage?.ciImage {
// deal with the scaledCIImage
} else {
// do something else to remedy. The method can still continue running
}
If your method couldn't continue if the value is nil, then you can consider writing a guard statement:
guard let scaledCIImage = scaledImage?.ciImage else {
// you need to return some value or call "fatalError()" here
}
If you are absolutely sure that the value could not be nil, force unwrap it:
let scaledCIImage = scaledImage!.ciImage!
For the second error, you can fix it like:
// with force unwrapping
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])!.outputImage!
// if let
if let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])?.outputImage {
// ...
}
// guard let
guard let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])?.outputImage else {
// ...
}
You can chain all of these together in a big if let or guard let statement like rmaddy has shown.
I am not able to figure this one out by my self. I am retrieving some settings stored in Core Data, and print these setting to some UITextFields. This works fine in another VC in the same project but here I get "unexpexpectedly found nil while unwrapping optional value".
I XCode I can see that the values are there? Why do I get this crash?
Please see attached screenshot.
This is the current code I am down to now. Still the same error message in XCode
func getSettingsFromCoreData() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "DeathMatchSettings")
do{
let results = try context.fetch(request)
let managedObject = results as! [NSManagedObject]
let getDMSettings = managedObject[0]
guard let playerOne = getDMSettings.value(forKey: "playerOne") else {
return
}
print(playerOne)
txtPlayerOne.text = String(describing: playerOne)
}catch{
fatalError("Error in retreiving settings from CoreData")
}
}
Player1 can be nil. You are trying to force downcast it to a value, but it is a fatal error in swift. Use an if let statement to test the value:
if let playerOne = getDMSSettings.value(forKey: "playerOne") as? String {
print(playerOne)
txtPlayerOne.text = playerOne
}
Read more about type casting in docs:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html
You can also use guard statement to unwrap your optional variable. It is better to use forced unwrapping only if you are confident that variable has non-optional value.
do {
guard let playerOne = getDMSettings.value(forKey:"playerOne") else {
return
}
print(playerOne)
txtPlayerOne.text = playerOne
}
This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 6 years ago.
Hi I'm having a problem with NSJSONSerialization reading JSON from api
code:
func json() {
let urlStr = "https://apis.daum.net/contents/movie?=\etc\(keyword)&output=json"
let urlStr2: String! = urlStr.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
let url = NSURL(string: urlStr2)
let data = NSData(contentsOfURL: url!)
do {
let ret = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(rawValue: 0)) as! NSDictionary
let channel = ret["channel"] as? NSDictionary
let item = channel!["item"] as! NSArray
for element in item {
let newMovie = Movie_var()
// etc
movieList.append(newMovie)
}
catch {
}
}
And I am getting this error
let ret = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(rawValue: 0)) as! NSDictionary
fatal error: unexpectedly found nil while unwrapping an Optional value
How do I fix it?
The return type of the contentsOfURL initializer of NSData is optional NSData.
let data = NSData(contentsOfURL: url!) //This returns optional NSData
Since contentsOfURL initializer method returns an optional, first you need to unwrap the optional using if let and then use the data if it is not nil as shown below.
if let data = NSData(contentsOfURL: url!) {
//Also it is advised to check for whether you can type cast it to NSDictionary using as?. If you use as! to force type cast and if the compiler isn't able to type cast it to NSDictionary it will give runtime error.
if let ret = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) as? NSDictionary {
//Do whatever you want to do with the ret
}
}
But in case of your code snippet you're not checking the whether data that you get from contentsOfURL is nil or not. You're forcefully unwrapping the data and in this particular case the data is nil so the unwrapping is failing and it is giving the error - unexpectedly found nil while unwrapping an Optional value.
Hope this helps.
code:
var json:NSString;
json = NSString(format:"{\"und\":[{\"value\":\"2324\"}]")
var data:NSData = json.dataUsingEncoding(NSUTF8StringEncoding)!
var dataDic:NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error:nil) as! NSDictionary
I formed my own json and when i try yo parse it give error as "Unexpectedly found nil while unwrapping an Optional value".I assume that the cause of issue is passing empty json for pasing.I do not know how to solve this problem?.thanks in advance
let jsonString = "{\"und\":[{\"value\":\"2324\"}]}"
if let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
var error: NSError?
if let jsonDict = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: &error) as? [String:AnyObject] {
if let dictionaries = jsonDict["und"] as? [AnyObject] {
for dictionary in dictionaries {
if let value = dictionary["value"] as? String {
println(value)
}
}
}
}
}
As Martin R suggested The problem is in your json String. so just modify it like this:
"{\"und\":[{\"value\":\"2324\"}]}"
You forgot to add } at last.
Without } it can not be cast as NSDictionary thats why it become nil at run time.
You cant declare a variable uninitialized as you did. Replace
var json:NSString
to
var json:NSString!
The exclamation declaration will automatically unwrap the optional value where it is used (so you do not need to write json!) but you need to ensure that it is initialized somehow.
Ok so I am trying to run this code but I keep on getting this error: fatal error: unexpectedly found nil while unwrapping an Optional value. I don't understand what it means or why im getting it. Can someone please help me. Thanks
query.whereKey("accepted", equalTo: PFUser.currentUser().username)
query.whereKey("username", containedIn: PFUser.currentUser()["accepted"] as [AnyObject])
All you have to do is this:
if let currentUser = PFUser.currentUser() {
query.whereKey("accepted", equalTo: currentUser.username)
if let someArrayObject = currentUser["accepted"] as? [AnyObject] {
query.whereKey("username", containedIn: someArrayObject)
}
} else {
// currentUser does not exist, do error handling
}
According to objective-c documentation of PFUser.currentUser(), which I'm assuming translates into a Swift optional, it could easily return nil. So you need to do something like:
if let currentUser = PFUser.currentUser() {
query.whereKey("accepted", equalTo: currentUser.username)
if let someArrayObject = currentUser["accepted"] as? [AnyObject] {
query.whereKey("username", containedIn: someArrayObject)
}
} else {
// currentUser does not exist, do error handling
}
Not sure what that second query line is, and what the someArrayObject is, so you might look further into that. But your error is either related to you dereferencing the currentUser() which could be nil, or the use of as and not as? in the second query line.
Solution to either is to use proper unwrapping of the potential optional values.