unexpectedly found nil while unwrapping optional value, but there is some value - ios

I am trying to get do a GET request, and save the following results from into NSMutuableArray. Then I am trying to load the following data I got into a tableview, but I am getting an "unexpectedly found nil while unwrapping optional value" whenever I try to configure the number of rows.
var dataArray:NSMutableArray?
Alamofire.request(.GET, "SOMERANDOMWEBSITE") .responseJSON { response in
// using if-let syntax to save json into our NSMutuableArray
if let JSON = response.result.value {
self.dataArray = JSON as? NSMutableArray
}
}
When i try to configure the number of rows:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return self.dataArray.count
}
It gives me an error: "unexpectedly found nil while unwrapping optional value". But what's strange is that when I create a random button to see if the .count is indeed nil:
#IBAction func function(sender: AnyObject) {
print(self.dataArray?.count)
}
it returns me with Optional(2) instead of nil. Any ideas?

You made your array an Optional. We can see that here:
print(self.dataArray?.count)
So until it's populated in Alamofire's closure (the network request happens in the background), it is nil.
You quote:
return self.dataArray.count
but actually you probably have done
return self.dataArray!.count
This is why it crashes.
So you have to declare another option for count for when it's nil. A solution could be to safely unwrap the array then return the count or return a default value:
if let array = self.dataArray {
return array.count
}
return 0
This same logic can be expressed in a single line, as #brian-nickel notes in the comments:
return self.dataArray?.count ?? 0
Also, as stated by #vadian in the comments, absolutely, an Optional array makes little sense here, it would be better to just have a non-optional empty array from the beginning.

It's not strange, it's asynchronous.
Initially you declare dataArray as optional (aka nil) but don't initialize it.
The first attempt to update the table view fails (crashes) because calling count on nil is a bad idea.
Meanwhile the asynchronous request method returns the data and assigns it to dataArray which has now an (optional) value.
That's why you get a result in function.
Solution is to declare and initialize the array as non-optional Swift type.
var dataArray = [AnyObject]()
Probably there is a more specific type than AnyObject
and assign the returned data accordingly casting the result to the "better" type.
Basically declaring table view data source arrays as optional is absurd since your table view is always non-optional.

Related

calling function in viewDidLoad crash

Calling parseString crashes my application. myOptionalString is getting set from didSelectRowAtIndexPath in a tableview. The information is definitely get passed to this view controller.
The method also works if called from a button press. But in any life cycle method I try I get unexpectedly found nil while unwrapping an Optional.
override func viewDidLoad() {
super.viewDidLoad()
if let myUnwrappedString = myOptionalString{
print(myUnwrappedString) //<-- prints out string
confidence.text = parseString(myUnwrappedString) //<-- unexpectedly found nil while unwrapping an Optional crash
}
}
//this method works if called on a button press but crashes in viewDidLoad
func parseString(myString: String)->String{
return myString.substringFromIndex(myString.rangeOfString(" ")!.endIndex)
}
Your error come from your function parseString, let's see why. If you see carefully your function you're make a force-unwrapping of an optional value in your case the myString.rangeOfString(" ")!. This is not recommended at all.
If we pass the string "Confidence: 63%" to the function the function works properly and returns "63%", but it works because it have the " " string inside, if for some reason you pass some string that don't have it it will crash (e.g "Confidence:63%").
So one of the correct ways of implement this function can be using the guard statement using optional binding avoiding any force-unwrapping:
func parseString(myString: String) -> String? {
guard let range = myString.rangeOfString(" ") else { return nil }
return myString.substringFromIndex(range.endIndex)
}
In the above function you return nil in case of not exist the " " in the string and avoid the runtime error.
I hope this help you.
I'm guessing your problem lies in this line:
myString.rangeOfString(" ")!
rangeOfString returns an optional Range<Index>? value, meaning that if the character you are looking for is not present in the string, you will get the value nil in return. In other words, if there is no space in your string, you get a nil value for your range.
That value you then force unwrap with !, and then you use it to call substringFromIndex. This means that if the range was actually nil, you use that nil value to try to create a substring from its endIndex... which you cannot...so it crashes.
One way of solving this could be to use a guardto make sure that you actually found a range in your string. If you don't, then you just return an empty String...or do something else that suits your use case better.
Here is an example:
func parseString(myString: String)->String{
guard let range = myString.rangeOfString(" ") else {
return ""
}
return myString.substringFromIndex(range.endIndex)
}
Hope that helps you.

Access Optional property in multiple function for calculations - Swift

I have a NSObject Subclass. Say CityWalks
class CityWalks{
var totalCount:Int?
}
How do I use this property further? Should I check the nil coalescing every time this value is accessed.
example:
let aObject =
say in one fucntion (function1()) , I need to access this value, then it would like (aObject!.totalCount ?? 0)
func function1(){
...Some Access code for the object....
(aObject!.totalCount ?? 0)
}
Similarly in every other function(function2()) , I will have to write the same code.
func function2(){
...Some Access code for the object....
(aObject!.totalCount ?? 0)
}
So, what could be a better approach for such field, considering this property might receive a value from server or might not.
If you have a default value for this property just assign this value as default value.
class YourClass {
var totalCount = 0
}
I'd recommend you avoid using an optional value if it's possible. Because optional values its a first place when you can get an error.
As stated in the comments and the other answer using an optional is not really optimal in your case. It seems like you might as well use a default value of 0.
However, to clarify, you have to check the value when unwrapping the optional.
Sometimes it's possible to pass an optional to UIElement etc and then you don't really need to do anything with them
There are pretty ways of checking for nil in optional values built into swift so you can build pretty neat code even though you work with optional.
Look in to guard let and if let if you want to know more about unwrapping values safely.
if let
if let totalWalks = aObject?.totalCount {
//operate on totalWalks
}
guard
guard let totalWalks = aObject?.totalCount else { return }
//operate on totalWalks
There are also cases where you will want to call a function on an optional value and in this case you can do so with ?
aObject?.doSomething()
Any return values this function might have will now be wrapped in an optional and you might have to unwrap them as well with an if let or guard
When working with optionals you should try to avoid forcing the unwrap with ! as even though you at the moment know that the value is not null that might after a change in the code not be true anymore.

NSData: unexpectedly found nil while unwrapping an Optional value

It may be the basic swift quetion, But i am new to swift or iOS development. I am getting the error fatal error: unexpectedly found nil while unwrapping an Optional value
For the function bellow
func Call() -> NSData?
{
let nilObj: NSData? = nil
if(false){
// Doing something
}
else
{
return nilObj!
}
}
I just want to return the nil NSData in else condition but i am getting error. I am sure i am missing something obvious, Can anybody help.
You declared nilObj as optional and initialised it with nil. Then in your else clause you are trying to unwrap that. For fixing the issue you just need to remove that !
Change your code to:
func Call() -> NSData?
{
let nilObj: NSData? = nil
if(false)
{
// Doing something
}
else
{
return nilObj
}
}
Well, error says it all! You are trying to forceful unwrap an optional. You should use if let syntax while unwrapping an optional.
Optionals in swift can be confusing at first but it helps to keep in mind that they are just an enum like:
enum Optional<T> {
case None
case Some(T) // swift enums can have data associated to them
}
If you are sure your optional has non-nil value, that is, it is a .Some, you can access this underlying value through the exclamation mark ! operator.
In short, force-unwrapping optional! is saying "Ok, I'm sure this optional contains non-nil value. Give it to me."
This is what's called force-unwrapping. You're telling the system to access the value corresponding to .Some(T) although you're not checking whether your optional is a .Some or a .None. If you force-unwrap with ! and your optional turns out to be a .None, you will get the runtime error you got unexpectedly found nil while unwrapping an Optional value.
As a rule of thumb you should always check your optionals before unwrapping them. In few occasions you should assume an optional is non-nil and force-unwrap it. Even an IBOutlet can turn out to be nil if you try to access it in prepareForSegue for example. XCode automatically makes outlets implicitly unwrapped because for most of your view controller's lifecycle they won't be nil. But you still have to take care for yourself of these less common edge cases in which they are nil.
You can check if an optional has non-nil value the standard way with
if optional != nil {
// force-unwrapping after nil check is fine
optional!.someMethod()
} else {
// 'optional' is nil
}
A more idiomatic way to do it with swift is through optional binding.
// binds the constant 'value' to your optional if it is non-nil
if let value = optional {
value.someMethod()
} else {
// optional is nil
}
A third way to check is with guard statements. The semantics of guard statements is a bit different from the previous ones though. You can also mix guard statements and optional binding.
guard optional != nil else {
// optional is nil.
// by the end of this branch you must exit the block that
// encloses the guard statement, such as with a return or break
return
}
// if control reaches here you're guaranteed optional is non-nil
Guard statements are a neat feature in swift because you can focus on the conditions you want, as opposed to what you don't want. It also keeps the code that handles a violated requirement next to the respective requirement. Compared to doing the same thing with an if statement, guards improve readability by making your intents explicit.
To know more have a look at the basics section of the swift documentation.

executeFetchRequest fatal error in Swift

I'm new to Swift and I'm trying to learn while I write some Core Data related methods. I need to fetch some entities, this is a code snippet of the method I call for that:
let results = context.executeFetchRequest(fetchRequest, error: &error) as! [MyCustomEntity]?
if let myEntities = results {
let lastEntity = myEntities.last!
return lastEntity.entityNum.integerValue
}
When I run the app, it crashes at the line let lastEntity = myEntities.last! and I get this message in console:
fatal error: unexpectedly found nil while unwrapping an Optional value
However, error is nil at that point. I followed an example to write that code, and as far as I understood, the if statement block should only be executed if there are results... right? What is it happening there?
Thanks in advance
I'm assuming that the array that you're receiving is empty. You are using optional binding correctly to determine whether you receive an array or not, but that does not guarantee that you have elements in the array.
The last method on Array returns an Optional; it returns nil when the array is empty:
/// The last element, or `nil` if the array is empty
var last: T? { get }
You are unwrapping the return value from myEntities.last, which means your app crashes when myEntities is an empty array.
To make this code safe you'll additionally need to check the return value from the last method.

fatal error: unexpectedly found nil while unwrapping an Optional value(When adding to a array)

I have some code that receives value from a segue and replaces a certain element of an array with the index number that I have.
The initialization of the variables is:
var noteTitles: [String] = ["Sample Note"]
var noteBodies: [String] = ["This is what lies within"]
var selectedNoteIndex: Int!
var newTitle: String!
var newBody: String!
and I have a segue that makes the last 3 values the values that I want them to be.
under viewDidLoad(), I have this:
if newTitle == nil && newBody == nil {
}
else {
println("\(newTitle)")
println("\(newBody)")
println("\(selectedNoteIndex)")
let realTitle: String = newTitle
let realBody: String = newBody
let realIndex: Int = selectedNoteIndex
noteTitles[realIndex] = realTitle
noteBodies[realIndex] = realBody
}
My logs show this:
New Note Title
This is what lies within
nil
fatal error: unexpectedly found nil while unwrapping an Optional value
and I get
Thread 1: EXC_BAD_INSTRUCTION(code=EXC_i385_INVOP,subcode=0x0)
on the line
let realIndex: Int = selectedNoteIndex
Can anyone tell me what I'm doing wrong?
var varName: Type! declares an implicitly unwrapped optional.
It means that it will be automatically unwrapped when accessing the value with varName, i.e. without using varName!.
Thus, accessing the implicitly unwrapped optional selectedNoteIndex with let realIndex: Int = selectedNoteIndex when its value is actually nil results in the error you got.
Apple's Swift Guide states that:
Implicitly unwrapped optionals should not be used when there is a
possibility of a variable becoming nil at a later point. Always use a
normal optional type if you need to check for a nil value during the
lifetime of a variable.
The reason I was getting these errors is because while segueing back to the main view, I was not using the proper unwind segue, and instead using another show segue, which erased all data that had previously been within the view controller. By creating a unwind segue, I was able to keep the values before the segue to the detail view and prevent the error.
Because you did not assign value for selectedNoteIndex so it shows nil. First, you have to check whether its not nil value.
if let selectedNoteIndex = realIndex{
let realIndex: Int = selectedNoteIndex
}

Resources