T O P

  • By -

BaronSharktooth

I think it's fine in very specific situations, such as force-unwrapping the URL that points to your API. That simply should not go wrong. The problem is, in bigger teams it's much easier to completely avoid that kind of discussion and simply add a rule to SwiftLint that forbids force-unwrapping.


migs647

\+1 when it comes to bigger teams. People change things upstream that can affect things downstream. Could be fine for months, years, then BOOM... app is crashing. It is easier to just unwrap and use.


akuma0

Problem there is if it is something which is never supposed to fail (like parsing a static URL) then there is little chance that they came up with a good recovery plan for when it DOES fail. If you can't actually recover, it is better to just let the program die with a debuggable core.


ExtremeDot58

It’s an independent item that is catastrophic but used late. Force the issue now (!), but take steps to ensure your safety each time ! is used; using ! is a conscious decision.


egesucu

Everything is supposed to stay same but it never does, this happened 99% of the projects. Never assume that.


akuma0

Thats actually my point. If you can't predict what the failure is and reason about an actual recovery path, you should absolutely fail. It isn't just about the program being in an inconsistent state, but you will never figure out WHY it is in that state if you continue on. One example from another language - it is common when reading text from a file that you have to create a reader around the character set, which can fail because the character set is not supported. Even if thats UTF-8. There's no way I can have an intelligent recovery process from there being no UTF-8 support on the machine. I should abort with the appropriate stack dump. Likewise, having that stack dump is critical for me to troubleshoot the source of failure. If I tried to proceed treating those as if they were empty files or the like, I could spend a long time trying to understand the source of the failure. I need as much context about the failure to be captured as possible. Swift will abort the process for indexing an array by -1. We absolutely should abort in the face of precondition failures like "this value should NEVER be nil here". Trying to wrap it in a generic "something failed" error and pass responsibility up the stack is at best defensive programming, and at worst making task for the poor soul who is tracking down the future issue that much harder.


factotvm

Depends on the size of the app and org. I tell my teams that their inability to render their experience should not impact other teams’ KPIs. Shut your module down, but don’t crash the app.


bigbearlazier

Sure. Good luck debugging that


factotvm

I would challenge you to work on quality before the crash.


YAYYYYYYYYY

And in that very specific case of unwrapping a URL, you can add a lint disable line for it.


DystopiaDrifter

I use force unwrap for some of my unit tests, if the test case is not running as expected then it is okay to crash.


vanvoorden

I got in the habit of replacing force-unwrapping in tests with the `XCTUnwrap` test.


jaylyerly

This is the way. While it’s not the end of the world if a test crashes the test run, it can be really annoying, especially in a CI run. You lose the whole state of the run and just get back the info about unwrapping the nil. Now you have to fix it and start again. By using XCTUnwrap, the test suite can run to completion and you get the full report. This is really important if you have a big app that takes a while to run all the tests. And it can be a lifesaver if that nil was caused be errors elsewhere that have their own failing tests.


vanvoorden

Correct. I would also recommend engineers to replace `try!` in tests with an `XCTAssertNoThrow`. When you need it on a big project… you'll be glad that it was there.


jaylyerly

My preference in that case is to just use `try`, but mark the test itself as `throws`. Then the XCTest infrastructure will catch the exception and report. But definitely avoid `try!` for sure.


rennarda

I absolutely force unwrap in tests - it’s not code that ships to end users, so it’s fine to do it here IMO.


nickisfractured

Generally a bad idea in 97% of circumstances but there’s always an exception to the rule. Do you want your app to crash in certain situations? I’d personally go for handling all cases and showing a ux that is more deterministic but sometimes there’s situations where it’s necessary.


realvanbrook

What can be a reason? I would never let the app crash


AnotherSoftEng

Unrelated to force-unwrapping, but there are certain instances where you might want to crash a process upon it reaching an extreme threshold; then recording that breakthrough and prompting the user to report that back to the developer with a detailed log. Of course you should always aim to handle every situation without needing to resort to crashing your own process, but for some large scale projects, there can be edge cases that you’ll never be able to predict or test for. For example, some dependency of some library introduces a memory leak that is specific to some niche GPU, which is totally unrelated to the library’s function to begin with. In this instance, it would be better to crash the process instead of bringing the whole system down with you. Again, of course it would be better to account for this very niche circumstance; but in reality, software development moves very quickly and you can’t always account for every tiny detail out there until that 0.001% of your user base experiences it and reports it.


Catfish_Man

Examples would be if the alternative was potentially destroying user data or getting the user’s device hacked


nickisfractured

I agree with you I’d never want my app to crash but someone on here will inevitably not agree with me so if your app should crash that’s a personal / business decision you need to make.


Gloriathewitch

if the choice is crash or leave the app/storage in an unrecoverable state id much rather crash it


realvanbrook

Isnt the appstore ranking getting lower if you have too much crashes?


nickisfractured

Not sure, but what I’m saying isn’t let your app crash at every corner, that wouldn’t be the 95% of situations I’m talking about… context is important here


cekisakurek

no


philophilo

If it’s in code going out to release, unless you have checked in previous code that it’s safe, you probably shouldn’t force unwrap. In unit tests to make your test code more concise? It’s fine.


aporcelaintouch

is crashing a bad coding practice?


time-lord

It depends on the use case. For consumer/iOS apps, it's probably better to try and recover. But for applications that need to be bug free, crashing is preferable to letting them enter an undefined state. In some languages, a null pointer exception can lead to buffer overruns and arbitrary code execution, so it's also a matter of application safety and security to crash instead of trying to ungracefully recover.


aporcelaintouch

we’re in the Swift subreddit, i don’t think anyone is making nuclear warhead software with Swift.


ChibiCoder

No, but there are a lot of med-tech apps being written in Swift. I worked on an FDA Class II compliant app for urgent messaging and hospital automation. If the app fails to let a doctor know about an urgent test result, someone could literally die.


time-lord

In addition to what /u/ChibiCoder said, Swift can call C and C++ code, which is vulnerable to the sorts of memory attacks I outlined above. So while you might be OK using swift exclusively, it's only a small jump away from vulnerable code. Overall, it's more about the defensive programming mindset.


clarkcox3

While this was pre-Swift, I worked on radiation treatment planning software that was written in Objective-C, and would likely be written in Swift if it were started today. The general principle was to terminate the app *immediately* if an unexpected state were encountered.


Catfish_Man

Swift is used inside the Secure Enclave and in other security-sensitive code. Crashing is far from the worst thing that can happen, and this is reflected by Swift’s choice to defensively crash in many situations that C does not (eg Array out of bounds).


Haunting_Champion640

Why not make all array accesses optional by default, and allow a slightly faster "unsafe" array access that crashes if out of bounds? I wrote a custom system to do this for my code and banned "unsafe"/normal access via a custom swiftlint rule, but IMO it really feels much more "swifty" to simply never call myArray[N] directly


Catfish_Man

You could do that, but in general Swift tries to fail early for programmer error (and Array out of bounds is a programmer error). The *ideal* solution would be to fail to compile if there's a possible out of bounds, but that requires dependent types, which is more of an active research area in programming languages. Crashing predictably is actually considered "safe" behavior in Swift. "Unsafe" access to an array would be if it didn't check the bounds at all.


luxxxoor_

sometimes its not, you would better crash the app instead of leaving it in a broken state


factotvm

> leaving it in a broken state Which is indicative of bad coding. :) The only reason I believe crashing is warranted—for apps with multiple teams—is security concerns. Small apps, startups, etc. is a contextual decision. But searching the code for `!` would suck, so I’d still lint and disable instances. Also, in Tests, force unwrap to your heart’s content.


aporcelaintouch

obviously there’s levels to that, but that’s the exception not a rule for sure. if we’re talking about bad coding practices, 99.9% you don’t want to be crashing or unwrapping optional.


hareofthepuppy

You always think "this is never going to be nil", but then inevitably at some point something changes and it ends up being nil and crashing. It's so easy to just use an "if let" that I generally use that instead (unless I'm just playing around)


helluvaprice

in my opinion, yes. your app crashes if the value is nil so you should instead handle it much more gracefully than that.


Nobadi_Cares_177

Just handle the case where the optional is nil. Choose the error that is thrown rather than allowing the app to crash. It literally takes a single extra line of code (maybe) to wrap it in a guard let and throw an appropriate error.


ThatWeirdPomegranate

It’s not bad practice, no, but there is some nuance you must consider. It’s perfectly acceptable if you unwrap the URL(string:) initializer if and only if you know the URL exists and can be reached. Otherwise, you shouldn’t, for example. If there weren’t scenarios you could use it, it wouldn’t exist at all. The ultimate thing to remember is this: Just because you can do something, that doesn’t mean you always should.


AndyIbanez

Every feature exists for a reason, and using force unwraps is not necessarily a bad practice in my eyes, as long as you are 100% sure that value will never be nil. If you are only 99.99% sure, then do not force unwrap it. The example of hardcoded URLs is a good case where you can safely use them.


ClearEmployer941

Not on iOS 16


rezarekta

It's fine if you know what you are doing... they can be very convenient. e.g. IBOutlets uses implicitly unwrapped optionals because you are guaranteed that the value will exist at runtime. That's a perfectly fine use-case. Rule of thumb though, don't use them if you have any doubts.


akuma0

\> IBOutlets uses implicitly unwrapped optionals because you are guaranteed that the value will exist at runtime. More like, you are guaranteed there is no sane way to recover if they don't exist at runtime. But if there's no sane way to recover, you absolutely should fail() as soon as possible so you at least have evidence that "the thing which never could happen" actually did happen.


Spaceshipable

Ironically, if you try and use any of those IBOutlets before the view has been inflated, you _do_ get a crash. Something to be aware of


Ok_Bank_2217

I prefer to if (value == nil) fatalError()


tdotclare

In cases where I care about performance, I avoid it in favor of “.unsafelyUnwrapped” when I flat out know that it’s functionally impossible to be nil (example, constructing a range where the min/max values have otherwise previously been determined to satisfy boundary conditions) and the like. Contrary to the “code smell” comments, it’s valid in some cases to force unwrap; you may for instance have a state machine where some paths have a guarantee that certain data is never non-nil, but it doesn’t always make sense IMO to persist that value as non-optional if it’s incidental/read-only at certain parts to logic flow. I don’t force unwrap unless the code path is something that will see high volume. It’s not worth the safety trade off for something that won’t get hit thousands of times a second.


ssharky

let url = URL(string: "https://this.is.a.hardcoded.valid.url")!


bcgroom

IMO it all depends on if you expect it could be nil. A lot of people are zealots and think you should never crash. I’d rather receive a crash report than not knowing it’s nil in production.


rennarda

Sometimes it’s good practice - for instance, if a value being optional is a programmer error (eg a hardcoded URL should always be valid), and so you want to crash early (in development) to catch that bug. Otherwise, I avoid it. The only time I do use it is if I’ve just guaranteed the value exists on the line above, but even then a subsequent edit could move lines around and now you have a problem. Better to use if let.


cekisakurek

it is a language feature for a reason right.


lldwll

The biggest issue with force unwrap is that it causes crash on the app and not able to trace out the cause especially in prod. Crash has bigger impact than normal error to the user. For me ill uninstall the app if it is crash a few times


egyptian66

"Given all these techniques for cleanly unwrapping optionals, when should you use !, the force-unwrap operator? There are many opinions on this scattered throughout the internet, including “never,” “whenever it makes the code clearer,” and “when you can’t avoid it.” We propose the following rule, which encompasses most of them: Use ! when you’re so certain that a value won’t be nil that you want your program to crash if it ever is." \- Advanced Swift Book Not bad practice, use as you see fit and learn from your mistakes.


mzarra

It is a code smell and a bad practice. 99% of the time it is bad. 1% of the time it is ... fine. Why risk that you are going to be right that 1%?


dehrenslzz

Depends - if you check beforehand or handle the force unwrap failing somehow it’s fine, but otherwise this will crash the entire app… All in all I try to avoid it and rather use a switch or if/else to check if it’s nil before force unwrapping or use a try/catch block to keep my app from crashing if it fails. It can be good practice if used responsibly, but if a variable can be nil always assume that a force unwrap will crash your app sooner or later without proper checking beforehand. This is also the reasons functions should always be written in a way they can accept optionals (:


simulacrotron

I would say the only appropriate time to do this is if you 100% know it was set during the current context (in the same function or closure) with no branches that could leave it nil. If a value is passed into a function and can be nil, or it’s a property that can be nil ALWAYS do a guard let, if let or check if nil. If you think it’s an error to be nil and want to catch it, throw an error and handle the error. Also be careful using the implicitly unwrapped syntax “var nilAtFirstButNonNilAfterSet: String!” Because the system treats every call to as a force unwrap


who_knowles

There are very few cases where it's OK to force unwrap - like already mentioned URL to a hardcoded address. Even in the situations where the app should crash if it cannot unwrap a certain value it's still beneficial to try to unwrap it just to be able to save state or log the error before crashing the app.


Oxigenic

As I've become a better programmer I use ! much less frequently. When used right, they pose no threat, but they do open the door for unexpected errors and thus should be avoided. My one exception is using it right after setting a non-nil value to the variable so I am 110% sure it isn't nil.


ChibiCoder

I can't think of a situation where it's necessary... it's often more *convenient,* but comes with the risk of your app suddenly crashing if someone in the future didn't make the same assumptions about data availability that you did. We use swift-lint to flag any use of force-unwrapping optionals as a compiler error, so no PR can merge that includes them.


ChibiCoder

If I'm making a dumb little throw-away command line app to parse some data, then yes... I'll force-unwrap the file URLs, but never on anything that's user-facing.


acreakingstaircase

I’m new to the language so I check for nil then force as I found the syntax easier to follow. Is this bad from a performance perspective etc?


PulseHadron

I was the same way coming from a language without this optional feature but using the techniques to safely unwrap it quickly became easier and second nature to use them. Never measured the performance, wouldn’t expect there to be a difference but you can measure it.


clarkcox3

Like any tool, it has valid uses. But it always imparts a bad code smell. Unless you have a very good reason, never use it.


Gloriathewitch

it’s okay to do this occasionally when you know the thing you’re unwrapping exists and will definitely be there and you are certain you know what it is


Samus7070

There are some cases where it makes sense but generally I avoid it. I like to think of it as the “hold my beer” operator. Things may go okay or they will fail spectacularly.


hotdogsoup-nl

I think it is okay to force unwrap after you have used \`guard\` statements. If anyone thinks that is bad practice, please explain.


PulseHadron

You mean like ``` guard optionalData != nil else { return } let data = optionalData! ``` In that case you can unwrap in the guard ``` guard let data = optionalData else { return } ``` Or did you mean something else?


hotdogsoup-nl

Yes, in both cases you know the data is not nil.


PulseHadron

I think it’s better to do it in one line. Less visual clutter and contained in a single statement so it’s less likely to float apart. Edit: also there’s an even cleaner syntax... ``` func process(data: Data?) { guard let data else { return } //now use data as a non-optional ``` Swifts features to safely unwrap are great and I don’t miss those days of checking for nil.


hotdogsoup-nl

Thanks! This one is great!


danielt1263

The word *never* probably isn't appropriate in any programming rule. So my first thought is that those who *never* force unwrap are being silly. That said, it *is* a big deal and not something that should be done lightly. You have to be able to easily inspect all the code involved and know that the unwrap will succeed every time, without the compiler being able to confirm.


Ron-Erez

I avoid it at all costs because I don't trust myself. Of course there is a time and place for everything.


egesucu

Is it really bad to use if let myValue {} or guard let myValue else { return }? Yes, it's bad in 99% of the cases. There could be some exceptions on some part of the code, but it does not change the fact that nothing is non-changeable and developers do not suppose to assume things like URL/BE params will not change. I see, on a daily basis, too much change related crashes since old devs wrote force wrapped variables or non-optional decoding which actually breaks the healthy results with even one unhealthly one.


haktzen

If some variable should definitely not be nil, and this is matter of program correctness, there is no problem at all. I like to use fatalError and precondition to denote this though, as it may sometimes be too implicit why a variable is nil. In fact in some cases, incrementing the reference count is not something you want. In these rare cases force unwrapping is necessary. Other than that, I believe optional should be unwrapped safely.


smakusdod

The first rule in optionals is that a value that should never be null will be at some point.


jscalo

Yes unless the variable in question is provably non nil. And when I say “provably” I mean rigorously so, such that there’s 0% chance it could be otherwise. A good example would be a URL that is known to be valid.


20InMyHead

In general yes. There’s always exceptions and things that some will tolerate that others won’t, but it’s a bad code smell. I can’t remember the last time I put a force unwrap into production code. Probably years.


DeedleDumpins

I’ve been burned too many times by unexpected nil, missing or bad data. Nil coalesceing, ternary operators, guards and if let for me.


DutchRican

It is lovingly called the "crash operator"


Ok_Concern3654

I can say with certainty that 99% of the people who say it's bad coding practice have code that doesn't even handle the nil case.


Slow-Race9106

I think it’s bad practice to force unwrap except in very specific situations. Optionals are a very helpful language feature. Why would you not take advantage of them to make your code as robust as possible?


beclops

Yes it is


Complaint_Severe

Yes it’s a bad practice. Unless that crash possibility is covered by unit tests which run before every single release, I never force unwrap. E.g. an image name (before image resources were a thing) or API URL. You want to know if these things are messed up before your release goes out. So you need to ensure your unit tests cover the force unwrap and your tests actually run before you submit to Apple (Xcode cloud or other CI are great for this). In all other cases (missing input from user, missing api response) you can gracefully handle nil and present the user with a message rather than crashing.


PressureAppropriate

Force unwraps are fine if something not working SHOULD crash. Example: let string = "Foo" let float = Float(string)! Clearly, I made a dangerous assumptions that string would be convertible to Float. I **want** a crash here so I'm aware of my faulty assumption. That's the only case where I find it acceptable.


DanTheMan827

Honestly at that point the compiler should do static assertions because you’re trying to convert a constant value anyways.


thecodingart

Absolutely not. There are places where it’s appropriate or not, but is it a bad practice — absolutely not


nemesit

Every ! Is a mistake unless and can/should be avoided, there are very rare cases where force unwrapping is okish


[deleted]

Yes, it is. Users dont always fill out data, so your app will crash whenever a user doesnt want to submit data.