unexpected nil

`
	init() {
		nextOrder =  self.AllItems.map{$0.order}.max()
		if nextOrder == nil {
			nextOrder = 0
		}
		nextOrder! += 1 // <--- Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
	}
`

I have to say, Swift is great - when it works!

Answered by darkpaw in 814554022

How have you defined nextOrder? Just as an Int??

Your code seems to work properly in an existing project of mine:

func abc() {
	var nextOrder: Int? = modelData.availableEvents.map { $0.category }.max()
	if nextOrder == nil {
		nextOrder = 0
	}
	nextOrder! += 1
}

No errors for me.

Accepted Answer

How have you defined nextOrder? Just as an Int??

Your code seems to work properly in an existing project of mine:

func abc() {
	var nextOrder: Int? = modelData.availableEvents.map { $0.category }.max()
	if nextOrder == nil {
		nextOrder = 0
	}
	nextOrder! += 1
}

No errors for me.

It may be because you do it in the init.

I propose to add a return.

init() {
		nextOrder =  self.AllItems.map{$0.order}.max()
		if nextOrder == nil {
			nextOrder = 0
      return // <<-- ADD THIS
		}
		nextOrder! += 1 // <--- Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
	}

or add an else:

init() {
		nextOrder =  self.AllItems.map{$0.order}.max()
		if nextOrder == nil {
			nextOrder = 0
		} else { // <<-- ADD THIS
		  nextOrder! += 1 // <--- Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
    }
}

I tested in playground in an init, and no crash:

class OrderTest {
    struct Order {
        var order: Int
    }
    
    var nextOrder: Int?
    var allItems : [Order] = []
    
    init() {
        nextOrder =  self.allItems.map{$0.order}.max()
        print("nextOrder", nextOrder)
        if nextOrder == nil {
            nextOrder = 0
        }
        print("nextOrder after test", nextOrder)
        nextOrder! += 1 // <--- Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
    }
}

let orderTest = OrderTest()

So problem is somewhere else.

Could you show the class or structure where this init() is ?

One way I could get it crash was by delaying the allocation of next order with a Dispatch:

class OrderTest {
    struct Order {
        var order: Int
    }
    
    var nextOrder: Int?
    var allItems : [Order] = []
    
    init() {
        nextOrder = self.allItems.map{$0.order}.max()
        if nextOrder == nil {
            DispatchQueue.main.async(execute: { // <<-- WITH THIS, IT CRASHES
                self.nextOrder = 0
            })
        }
        nextOrder! += 1 // <--- Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
    }
}

Did you show the exact and complete init() ?

Sorry, I accidentally accepted the wrong answer. nextOrder was a State var so I didn't think I needed to return it. Since I posted, I've been doing it a different way, and I didn't commit that attempt, so can't go back. It's all related to this: https://developer.apple.com/forums/thread/768948?page=1#814553022

I think the problem is more with Xcode's debugger. It's the least helpful debugger I've ever seen.

So, when you ask a question, please provide complete information. That will avoid we loose time in guessing.

Have a good day.

I suppose it wasn't so much a question as an example of how bad Xcode has become. The error says it unexpectedly found nil when unwrapping an optional Int that had just been set to an integer. That's not possible! If I need to return a value, the error should have said so. And don't get me started on how it shows errors dozens of lines above where the actual error is!

From 2009 to 2014 I used Xcode to write in C++, and it was much better at reporting problems. I know Swift is a relatively new language, but this is not good.

@cwt_

It is more a SwiftUI reporting issue than a Swift one. And we know SwiftUI is limited in its error reporting precision.

I’m glad to hear that you got this sorted. Just a bit of extra commentary…

The best way to avoid trapping in a force unwrap is to minimise your use of optionals. For example, I would’ve written the code in your first post like so:

nextOrder = self.allItems.map{$0.order}.max() ?? 0
nextOrder += 1

There’s no optional, and thus no force unwrap, and thus no possibility of trapping.

This can take a little getting used to if you’re coming from a C-based language, where everything is optional [1].

And that isn’t to say that you should never use force unwrap. It’s absolutely the right tool for the job sometimes. It’s just that fewer optionals means fewer states to track, and that usually means fewer bugs.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Well, every pointer and every object reference. Ironically, we’re talking about a number here, which can’t be optional in most C-based languages.

unexpected nil
 
 
Q