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.
Related
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.
I'm new to Swift...
Trying to display some API data from newsapi which was working fine, but after a few runs I started getting the
Fatal error: Unexpectedly found nil while unwrapping an Optional value error at line 12 (let articles = dataDictionary["results"] as! [[String: Any]])
let url = URL(string: "https://newsapi.org/v2/everything?sources=techcrunch&apiKey=d65fb8f01d8e42c7b106590d09149d39")!
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10)
let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) { (data, response, error) in
//This will run when the network request returns
if let error = error {
print(error.localizedDescription)
} else if let data = data {
let dataDictionary = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
let articles = dataDictionary["results"] as! [[String: Any]]
self.articles = articles
self.tableView.reloadData()
}
}
task.resume()
}
Any ideas?
Use guard let on this change:-
let articles = dataDictionary["results"] as! [[String: Any]]
to this line:-
guard let articles = dataDictionary["results"] as? [[String: Any]] else { return}
don't use ! until you sure this must have value
Also see this answer to avoid this !:- Guard not unwrapping optional
Your dataDictionary does not contain key like results. It has articles key value. So dataDictionary["results"] is a null object.
dataDictionary["results"] will be null so try using ? instead of !
let articles = dataDictionary["results"] as? [[String: Any]]
I think it will be
let articles = dataDictionary["articles"] as? [[String: Any]]
I guess this is basic Swift, so I'm a bit embarrassed to ask:
In my app, I download a plist file from a server as such:
Alamofire.download(url, to: destination).response { response in
if let url = response.destinationURL {
self.holidays = NSDictionary(contentsOf: url)!
}
}
The file is a valid file, and it is succesfully dowloaded and sitting physically in my Documents folder.
However, the app crashes on
self.holidays = NSDictionary(contentsOf: url)!
saying
Fatal error: Unexpectedly found nil while unwrapping an Optional value
What gives?
Your NSDictionary is failing to initialize, so when you try to force unwrap it (with the exclamation mark) it fails and crashes.
Try something like this:
if let dictionary = NSDictionary(contentsOf: url) {
self.holidays = dictionary
}
Alternatively you can use the guard statement:
guard let dictionary = NSDictionary(contentsOf: url) else {
print("NSDictionary failed to initialise")
return
}
self.holidays = dictionary
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
}
I'm working on a json retrieving project or whatever, and I'm getting a fatal error while unwrapping a json. I think that the issue is that url is nil and I'm trying to unwrap it, but I'm not sure.
func getXRPData(urlString: String){
let url = NSURL(string: urlString)
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) { (data, response, error) in
dispatch_async(dispatch_get_main_queue(), {
self.setLabels(data)
})
}
task.resume()
}
func setLabels(xrpDataL: NSData){
var jsonError: NSError?
var percent = "%"
var dollarSIGN = "$"
let json = NSJSONSerialization.JSONObjectWithData(xrpDataL, options: nil, error: &jsonError) as! NSDictionary
//supply of xrp
if let supply = json["supply"] as? String{
var numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
if let result = numberFormatter.numberFromString(supply){
var finalResult = numberFormatter.stringFromNumber(result)
totalXRP.text = finalResult
}
}
Instead of force unwrapping, you should unwrap the results of JSONObjectWithData with an optional binding (if let) and a conditional downcast (as?):
if let json = NSJSONSerialization.JSONObjectWithData(xrpDataL, options: nil, error: &jsonError) as? NSDictionary {
// Continue parsing
} else {
// Handle error
}
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.