Check for nil with guard instead of if?
Like some people already answered, you can use let
guard let preview = post["preview"] else { /* Handle nil case */ return }
If you are not using the variable, you can use an underscore to not declare the variable and avoid the warning.
guard let _ = post["preview"] else { /* Handle nil case */ return }
You can also do a regular boolean check instead of using let
guard post["preview"] != nil else { /* Handle nil case */ return }
A more general case for a boolean check on a guard
guard conditionYouExpectToBeTrue else { /* Handle nil case */ return }
If you want to be able to modify the variable, you can use var
instead of let
guard var preview = post["preview"] else { /* Handle nil case */ return }
Swift 3.0
You can combine var/let
with a boolean check by using commas between the statements.
guard let preview = post["preview"], preview != "No Preview" else { /* Handle nil case */ return }
Swift 2.x
You can combine var/let
with the boolean check by using where where
guard let preview = post["preview"] where preview != "No Preview" else { /* Handle nil case */ return }
using guard to check for nil without implicitly unwrapping
In your guard
code you would have to have a return statement in the else block. Like this...
guard json["error"] == nil else {
let error = json["error"]!
// handle error
return
}
// handle success
But you are correct. Having to force unwrap the error is not ideal.
So in this case. I think guard
is the wrong solution. Instead use if
but return from the conditional block. This removes the need for using an else block.
if let error = json["error"] {
print(error)
// handle error
return
}
// handle success...
// no need for else block. Just return from the if in the error case.
The difference between guard let
and if let
is where the unwrapped optional is scoped.
With guard it is scoped outside the block with if it is scoped inside the block.
Swift guard check for nil file - unexpectedly found nil
Combining guard
and forced-unwrapping is an oxymoron. One of the common uses of guard
is guard let
which safely guards against nil
and eliminates the need to force-unwrap.
I would redo your code to something like:
guard let imagePath = Bundle.main.path(forResource: imageName, ofType: "png"), let image = UIImage(contentsOfFile: imagePath) else {
print("\(imageName).png file not available")
return
}
// Use image here as needed
If you don't actually need the image but you just want to make sure an image can be created, you can change that to:
guard let imagePath = Bundle.main.path(forResource: imageName, ofType: "png"), UIImage(contentsOfFile: imagePath) != nil else {
print("\(imageName).png file not available")
return
}
Having said all of that, if the image is actually supposed to be in your app bundle and it is simply a temporary issue such as forgetting to target the file properly, then don't use guard and go ahead and force-unwrap. You want the app to crash during development early on so you can fix the problem.
let image = UIImage(contentsOfFile: Bundle.main.path(forResource: imageName, ofType: "png")!)!
One last thing. You can more easily get the image using:
let image = UIImage(named: imageName)!
Guard Let statement not triggering even when values are nil
If you are just checking that the text field is empty then you can do something like:
guard
let estimatedHeight = estimatedHeightTextField.text,
!estimatedHeight.isEmpty,
let locationDescription = descriptionTextView.text,
!locationDescription.isEmpty
else {
nameRequiredLabel.isHidden = false
heightRequiredLabel.isHidden = false
descriptionRequiredLabel.isHidden = false
print("User did not put in all the required information.")
return
}
Checkout out this answer: https://stackoverflow.com/a/24102758/12761873
guard let found nil
selectedRooms.text
cannot return nil
.
A UITextField
and UITextView
always returns a String
value. An empty String
(""
) is returned if there is no text in the UITextField and UITextView
. That's the reason else
part is not executing and rooms
value is nil
.
Now, in the below statement you're force-unwrapping(!
) the rooms
.
x = Int(ceil(sqrt(Double(rooms!))))
But, since the rooms
is nil
, so forcefully unwrapping it is throwing runtime exception.
Solution:
You need to add an empty check as well for the else
part to take effect, i.e.
guard let numberOfRooms = selectedRooms.text, !numberOfRooms.isEmpty else { //here...
return selectedRooms.placeholder = "type something"
}
How to use guard in swift instead of if
you can use guard as well and your code will be more readable
let firstName = "First"
let lastName = "Last"
let address = "" // empty
if firstName != ""
{
if lastName != ""
{
if address != ""
{
print(1,firstName,lastName, address)
} else {
print(1,"address is empty")
}
} else {
print(1,"lastName is empty")
}
} else {
print(1,"firstName is empty")
}
func foo(firstName: String, lastName: String, address: String) {
guard !firstName.isEmpty else { print(2,"firstName is empty"); return }
guard !lastName.isEmpty else { print(2,"lastName is empty"); return }
guard !address.isEmpty else { print(2,"address is empty"); return }
print(2,firstName,lastName, address)
}
foo(firstName, lastName: lastName, address: address)
/*
1 address is empty
2 address is empty
*/
foo(firstName, lastName: lastName, address: "Address")
/*
2 First Last Address
*/
Swift: Benefit of using a guard-statement?
I don't think that is a very good example of using guard, it is more common to use it with variables that might be nil (aka optional) or functions that might return nil. I suggest you read about the guard statement in the Swift Programming Language book (just scroll down a bit to "Early Exit")
We could make a better example from your code that is lacking some validation
func getEmail(email: String?) -> String? {
guard let input = email, !input.isEmpty else {
return nil
}
return input + "@somewhere.com"
}
Here we use guard to check that the parameter email
is not nil by assigning it to a local variable input
. If it is nil the function will return nil and otherwise it will check if it is empty and then it will also return.
If it is ok the function will continue and create and return an email address. Note that the function is declared to return an optional string since I think it is much clearer if a function like this returns nil rather than an empty string if it fails.
Swift why unwrapping optional by guarding against NIL is not working
The type of s
is still Optional
, so whether you did a nil
check or not is irrelevant. The nil
check is done in runtime, while the type system is doing a compile-time check. The only way to ensure s
can never be nil
is via optional binding if let
or guard let
.
Related Topics
Evaluate Bool Property of Optional Object in If Statement
How to Get Date and Time to Show a Clock in Uilabel
Asyncdetached Falling Back into Main Thread After Mainactor Call
How to Use .Svg Images in Swiftui
Open a Viewcontroller from Remote Notification
Difference Between? and ! in Swift Language
Round Top Corners of a Uiview in Swift
How to Work with Bindings When Using a View Model VS Using @Binding in the View Itself
(Swift) Nstimer Stop When Scrolling
Reading an Inputstream into a Data Object
Using Os_Log to Log Function Arguments, or Other Dynamic Data
Swift Realm, Load the Pre-Populated Database the Right Way
Uitableview - Multiple Selection and Single Selection
How to Bind a Variable to Multiple Alternatives in a Switch Statement
Include an Extension for a Class Only If iOS11 Is Available
Simple Clickable Link in Cocoa and Swift
What's the Difference Between Class Methods and Instance Methods in Swift