Swift NSObject property is not optional , but it prints optional [duplicate] - ios

This question already has an answer here:
Swift 3 incorrect string interpolation with implicitly unwrapped Optionals
(1 answer)
Closed 5 years ago.
let allPlaces = resultsArray.map({ (param) -> Places in
return Places(dictionary: param )
})
print("All Places \(allPlaces[0].placeName)")
The output of the above code is:
All Places Optional("Subway")
In the below code the var is not optional. But the print statement prints it as Optional. Should it not print All Places "Subway"?
class Places: NSObject {
var name:String!
init(dictionary:Dictionary<String, Any>) {
name = dictionary["name"] as? String
}
}

var name:String!
You have declared name as implicitly unwrapped optional. From Swift 3 onwards it will only be force unwrapped if they need to be type checked locally. Otherwise it will be treated as normal optional only.
print("All Places \(allPlaces[0].name)")
Here there is no type checking involved, so name would be still Optional.
If you do like
let name:String = allPlaces[0].name
print("All Places \(name)")
Output will be "All Places Subway"
or you need to force unwrap it
print("All Places \(allPlaces[0].name!)")
This would cause crash if the name is nil, you should take care of it. If there is a chance name can be nil then use var name: String? so compiler force you to unwrap explicitly.

Change 'as?' to 'as!'.
The exclamation point means it absolutely clear.
The question mark means optional binding.
[Source]
class Places: NSObject {
var name:String!
init(dictionary:Dictionary<String, Any>) {
name = dictionary["name"] as! String
}
}
Another way
print("All Places \(allPlaces[0].placeName)")
to
print("All Places \(allPlaces[0].placeName!)")
or
print("All Places \(allPlaces[0].placeName ?? "")")

Related

Safely unwrapping optional values and add it to Alamofire parameters [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have a computed property of type Parameters in my APIRouter
// MARK: - Parameters
private var parameters: Parameters? {
switch self {
case .searchForDoctors(let doctorsFilter):
var params: Parameters = ["main_category_id": doctorsFilter.0, "page": doctorsFilter.1, "specialty_id": doctorsFilter.2, "city_id": doctorsFilter.3, "region_id": doctorsFilter.4, "name": doctorsFilter.5, "company_id": doctorsFilter.6, "order_by": doctorsFilter.7]
return params
default:
return nil
}
}
some values in the Typealias called doctorsFilter are optional.
currently I have a warning asking me to provide default value for the optional values, and I don't want to provide default values , I want to check if the value exist to add it, otherwise i will not add the key and the value
how can I safely unwrap the optional values and add it to the parameters dictionary with out saying if let for all optional values?
example:
if let specialtyID = doctorsFilter.2 {
params["specialty_id"] = specialtyID
}
I don't want to unwrap it this way as I will check for all optional values and it will take more lines of code
EDIT:-
the DoctorsFilter type is documented, when I initialize an instance of type DoctorsFilter the autocomplete tells me which of them is what, I I've thought about making the DoctorsFilter class before but I'm looking for another way if any, maybe a built in reserved word can handle the whole situation! , I want to make it simple as much as possible.
making a function that handles the dictionary and returns it in DoctorsFilter class is an option. I'm thinking of adding this function to the APIRouter, is it fine to add it there? is it the rule of the APIRouter to handle the parameters ? or the APIRouter just interested in taking the parameters and will not handle it ?
There is no "one line" solution, but you can use KeyPaths to reduce the series of if let ... statements down to a loop.
Start by creating a struct for your filter rather than using a tuple.
To facilitate this, we define a protocol for Parameterable - This protocol requires a dictionary that maps parameter names (String) to the property (KeyPath) that holds that parameter name as well as a function to return the parameters dictionary.
protocol Parameterable {
var paramNames: [String:KeyPath<Self,String?>] {get}
func parameters() -> [String:Any]
}
Use an extension to create a default implementation of the parameters() function, as the code will be the same for all Parameterables. It iterates over the dictionary entries and uses the associated KeyPath to access the relevant property and put it in the output dictionary. If a given property is nil then it simply isn't added to the output dictionary, because that is how dictionaries work. No need to explicitly check.
(If you import Alamofire then you can use the typedef Parameters where I have used [String:Any])
extension Parameterable {
func parameters() -> [String:Any] {
var parameters = [String:Any]()
for (paramName,keypath) in self.paramNames {
parameters[paramName]=self[keyPath:keypath]
}
return parameters
}
}
Use this protocol to create a DoctorsFilter implementation:
struct DoctorsFilter: Parameterable {
var mainCategoryId: String?
var page: String?
var specialtyId: String?
var cityID: String?
var regionId: String?
var name: String?
var companyId: String?
var orderBy: String?
let paramNames:[String:KeyPath<Self,String?>] = [
"main_category_id":\.mainCategoryId,
"page":\.page,
"specialty_id":\.specialtyId,
"city_id":\.cityID,
"region_id":\.regionId,
"name":\.name,
"company_id":\.companyId,
"order_by":\.orderBy]
}
private var parameters: Parameters? {
switch self {
case .searchForDoctors(let doctorsFilter):
return doctorsFilter.parameters()
case .someOtherThing(let someOtherThing):
return someOtherThing.parameters()
default:
return nil
}
}
}
The other approach is to simply split your creation of the parameters dictionary into multiple lines; If you assign nil against a dictionary key then there is no key/value pair stored in the dictionary for that key. In this case I have left your tuple approach in place, but you could use the struct (and I strongly suggest you do so)
private var parameters: Parameters? {
switch self {
case .searchForDoctors(let doctorsFilter):
var params: Parameters()
params["main_category_id"] = doctorsFilter.0
params["page"] = doctorsFilter.1
params["specialty_id"] = doctorsFilter.2
params["city_id"] = doctorsFilter.3
params["region_id"] = doctorsFilter.4
params["name"] = doctorsFilter.5
params["company_id"] = doctorsFilter.6
params["order_by"] = doctorsFilter.7
return params
default:
return nil
}
}
If we want to handle mixed properties, rather than just optional strings, we need to modify the code slightly. We need to use PartialKeyPath. This makes the code a little more complex since the subscript operator for a PartialKeyPath returns a double optional. This needs to be handled.
protocol Parameterable {
var paramNames: [String:PartialKeyPath<Self>] {get}
func parameters() -> [String:Any]
}
extension Parameterable {
func parameters() -> [String:Any] {
var parameters = [String:Any]()
for (paramName,keypath) in self.paramNames {
let value = self[keyPath:keypath] as? Any?
if let value = value {
parameters[paramName] = value
}
}
return parameters
}
}
struct DoctorsFilter:Parameterable {
var mainCategoryId: String?
var page: String?
var specialtyId: String?
var cityID: Int
var regionId: String?
var name: String?
var companyId: String?
var orderBy: String?
let paramNames:[String:PartialKeyPath<Self>] =
["main_category_id":\Self.mainCategoryId,
"page":\Self.page,
"specialty_id":\Self.specialtyId,
"city_id":\Self.cityID,
"region_id":\Self.regionId,
"name":\Self.name,
"company_id":\Self.companyId,
"order_by":\Self.orderBy]
}
There are three primary ways to safely unwrap an optional. You can also provide default values if you wish to unwrap an optional.
Guard Statement Unwrapping
var firstString: String?
// In some cases you might performa a break, continue or a return.
guard let someString = firstString else { return }
print(someString)
If Let Unwrapping
var secondString: String?
var thirdString: String?
thirdString = "Hello, World!"
// Notice that we are able to use the same "IF LET" to unwrap
// multiple values. However, if one fails, they all fail.
// You can do the same thing with "Guard" statements.
if let someString = secondString,
let someOtherString = thirdString {
print(someString)
print(someOtherString)
} else {
// With this code snippet, we will ALWAYS hit this block.
// because secondString has no value.
print("We weren't able to unwrap.")
}
Default Value Unwrapping
var fourthString: String?
// The ?? is telling the compiler that if it cannot be unwrapped,
// use this value instead.
print(fourthString ?? "Hello, World")
In Swift it is recommended that anytime you see a ! that you use some form of unwrapping. Swift is very "Type Safe".
Here's a resource you can use for Optionals.
https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html
Your Solution
Your solution might look something like this.
private var parameters: Parameters? {
switch self {
case .searchForDoctors(let doctorsFilter):
if let mainCatID = doctorsFilter.0,
let page = doctorsFilter.1,
let specialtyID = doctorsFilter.2,
let cityID = doctorsFilter.3,
let regionID = doctorsFilter.4,
let name = doctorsFilter.5,
let companyID = doctorsFilter.6,
let orderBy = doctorsFilter.7 {
params: Parameters = ["main_category_id": mainCatID,
"page": page,
"specialty_id": specialtyID,
"city_id": cityID,
"region_id": regionID,
"name": name,
"company_id": companyID,
"order_by": orderBy]
return params
} else {
//Unable to safely unwrap, return nothing.
return nil
}
default:
return nil
}
}

How force unwrapping works in function parameters in Swift? [duplicate]

This question already has answers here:
In Swift, what does the ! symbol mean in a function signature?
(2 answers)
Closed 3 years ago.
I have one function in Swift like,
func getValue(param: String!) -> String {
//access param
//return a string
}
call is like,
let retVal = getValue(param: nil)
I expected that the param will try to force unwrap while taking into the function parameters and get crashed. But the code did not crash. Can anyone let me know what am I missing?
What will be different in case of the signature,
func getValue(param: String?) -> String
Here ! means the param will hold String value or nil. So when you assign nil to ! it is not supposed to crash.
But when you try to access that value, it will crash.
This modification in your code will cause a crash as we are trying to access the value inside the variable which is nil.
func getValue(param: String!) -> String {
if param.isEmpty {
return ""
}
return ""
}
let retVal = getValue(param: nil)
Another example:
var string: String!
string = nil //This will not crash, but after this line if you try to access or perform any operation on it, it will
Now about thisfunc getValue(param: String?) :
In this scenario the the param will be optional type unlike in the above scenario. So here you will have to unwrap it.
Implicitly unwrapped optional (or IUO) may still contain nil as a value! In case of IUO you will get a crash only when you call any method/variable on it (e.g. param.count) OR when you assign it to a NON-Optional variable which will led to force unwrapping operation:
var param: String! = nil
var nonOptionalStr: String = param //<- Crash because it will try to force-unwrap param
Another example of a crash:
func foo(param: String!) -> String {
return param //<- Crash! As return type is non-optional String it will try to force unwrap the param.
}
On the other hand IUOs (as well as Optionals) are also of type Any so if you pass a String! containing nil to a method which expects Any it will not crash because there will be no force-unwrapping operation as Any? can be easily cast to Any .
let str: String! = nil
print(str) //<- No Crash! Becaise print accepts Any, so there will be no force-unwrapping
//Output: nil
Another example with type Any:
var a: Any? = nil
var b: Any = a //<- No Crash! As (Any?) is kind of (Any), though you will get a warning from compiler: Expression implicitly coerced from 'Any?' to 'Any'
print(b)
//Output: nil

How to write swift code to display Yelp Star Images? [duplicate]

This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 5 years ago.
Hey I'm trying to use Yelp's Review API and am having trouble structuring/writing the code necessary to display the different Yelp Star Ratings. I have no problem getting the response (it's successful). Yelp has provided image assets of all their different star ratings (5, 4.5, 4 etc. stars). Because the rating response is as a Double, I converted that into a String value. As for knowing which to call, I created an enum class so that it knows which image name to use. Using that name, I can then use it to find the image asset I need.
Now that I structure the code this way, my app crashes. Xcode will build it but upon opening the app, it crashes.
Enum class:
import Foundation
import UIKit
enum Rating: String {
case five = "regular_5"
case fourAndAHalf = "regular_4_half"
case four = "regular_4"
case threeAndAHalf = "regular_3_half"
case three = "regular_3"
case twoAndAHalf = "regular_2_half"
case two = "regular_2"
case oneAndAHalf = "regular_1_half"
case one = "regular_1"
case zero = "regular_0"
}
Yelp Client Service class:
import Foundation
import Alamofire
import SwiftyJSON
class YelpClientService {
static func getReviews(url: String, completionHandler: #escaping ([Review]?)-> Void)
{
let httpHeaders: HTTPHeaders = ["Authorization": "Bearer \(UserDefaults.standard.string(forKey: "token") ?? "")"]
//removing diacritics from the URL
if let requestUrl = URL(string: url.folding(options: .diacriticInsensitive, locale: .current))
{
Alamofire.request(requestUrl, encoding: URLEncoding.default, headers: httpHeaders).responseJSON { (returnedResponse) in
let returnedJson = JSON(with: returnedResponse.data as Any)
let reviewArray = returnedJson["reviews"].array
print(reviewArray as Any)
var reviews = [Review]()
for review in reviewArray! {
let userName = review["user"]["name"].stringValue
let ratingDouble = review["rating"].doubleValue
let rating = String(ratingDouble)
let text = review["text"].stringValue
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let timeCreated = formatter.date(from: review["time_created"].stringValue)
let url = review["url"].stringValue
let review = Review(rating: Rating(rawValue: rating)!, userName: userName, text: text, timeCreated: timeCreated!, url: url)
reviews.append(review)
}
completionHandler(reviews)
}
}
else
{
print("invalid url")
completionHandler(nil)
}
}
}
Func in View Controller thats displaying the Star:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reviewCell", for: indexPath) as! ReviewCell
let review = reviewList[indexPath.row]
print(review.userName)
cell.userName.text = review.userName
cell.reviewText.text = review.text
cell.yelpStars.image = UIImage(named: review.rating.rawValue)
//cell.date.text = review.timeCreated
return cell
}
The error when I build is: fatal error: unexpectedly found nil while unwrapping an Optional value.
I'm not sure what went wrong. Is it correct of me to instantiate rating as a Rating type? Should I keep it String?
I realize this is long code but I hope someone can help! Thank you!
I am sure it would crash. The way you have written it. let ratingDouble = review["rating"].doubleValue you are expecting double. It would be 0, 4.5, 3.0 etc. Which would get converted to string "0","4.5" "3.0" etc.Then you try to initialise rating with Rating(rawValue : rating), Rating enum does not have these raw values as "0", "4.5" etc, so nil will be returned. You are force unwrapping it with '!", no doubt its crashing.
You will need to format your enum like this
enum Rating: String {
case five = "5.0"
case fourAndAHalf = "4.5"
case four = "4.0"
case threeAndAHalf = "3.5"
case three = "3.0"
case twoAndAHalf = "2.5"
case two = "2.0"
case oneAndAHalf = "1.5"
case one = "1.0"
case zero = "0.0"
getImageName()-> String {
switch self {
case five:
return "ImageNameForFive"
case fourAndHalf:
return "ImageNameForFourAndHalf.
......
}
}
}
and change
let rating = String(ratingDouble)
to
let rating = String.init(format: "%.1f", ratingDouble)
The error fatal error: unexpectedly found nil while unwrapping an Optional value. is thrown when Swift is unable to do an action usually when the targets are nil, empty, non-existent or undefined.
If a value could potentially be nil, empty, non-existent or undefined; it is known as an optional value. In order to use these values in our code, we must unwrap them. If the value is either nil, empty, non-existent or undefined, our app would most likely crash if it was not unwrapped safely.
To unwrap an object safely in swift we can either use if let or a guard statement. The code is written inside of this only runs if the object is not null.
It's good practice to safely unwrap all your objects in swift to prevent crashes. An example can be found below:
Safe Unwrapping
// initalize a string that may be nil (an optional)
var string: String? = nil
// create a random number between 0-2
let randomNum:UInt32 = arc4random_uniform(3)
// create a switch to set the string value based on our number
switch (randomNum) {
case 0:
string = "Some String"
default:
break
}
// attempt to print out our string
// using a guard statement
guard let string = string else {
// handle if string is null
return
}
// print the string from the guard
print(string)
// using if let
if let string = string {
print(string)
} else {
// handle string is null
}
Unsafe Unwrapping
// initalize a string that may be nil (an optional)
var string: String? = nil
// create a random number between 0-2
let randomNum:UInt32 = arc4random_uniform(3)
// create a switch to set the string value based on our number
switch (randomNum) {
case 0:
string = "Some String"
default:
break
}
// attempt to print our string by forcefully unwrapping it even if it is null causing a crash if it is null
print(string!)
So you can see the difference, in the second one the app would crash with the same error you are getting as it failed to unwrap an optional value in the event the random number is not 0.
It is possible to safely unwrap an object without using if let or guard. This is known as an inline conditional which is basically an if/else clause but quicker.
Inline Conditionals
// if the string is null, it will print the value beside the two `??`
print(string ?? "This is what is printed if the string is nil")
So now that you have all this knowledge, you can go ahead and take a look at your code to see if you are forcefully unwrapping any of your values. A hint is that you use the ! to do this.
Also, the enum that you made takes string values like "half" not double values even if it is a string like '0.5". So it could also crash
Some examples I picked out that may cause the crash are:
for review in reviewArray!
review["rating"].doubleValue
Rating(rawValue: rating)!
timeCreated!

Swift 3: Cant unwrap optional from Dictionary?

Ok I don't know what is going on here. I have a dictionary of Strings below:
var animals = ["max": "z", "Royal": nil] //store key pairs
and I am unable to print the value of the value in the key value pair without it printing "Optional" along with it.
I have tried using ! !! and casting as a String as well as the following:
var animalsToReturn = [String]()
if animals[selected]! != nil
{
if let pairName = animals[selected]
{
print("\(pairName)")
print("has pair",selected, animals[selected]!)
//trying to append to another array here
animalsToReturn.append("\(animals[selected]!)")
animalsToReturn.append(selected)
}
}
else {
print("no pair")
}
I check to make sure the value isn't nil, so it won't crash if I unwrap. But this is what is printed and the word Optional is appended to my other array:
You have included nil as a value, so the type of your dictionary's value is not String but Optional<String>. But fetching a value by key from a dictionary is itself an Optional. Therefore:
If your entry is present and is ultimately a String, it is an Optional<Optional<String>> and you have to unwrap it twice.
If your entry is present and is ultimately nil, it is an Optional wrapping nil.
If your entry is not present, it is nil.
You can readily test this as follows:
func test(_ selected:String) {
var animals = ["max": "z", "Royal": nil]
if let entry = animals[selected] { // attempt to find
if let entry = entry { // attempt to double-unwrap
print("found", entry)
} else {
print("found nil")
}
} else {
print("not found")
}
}
test("max") // found z
test("Royal") // found nil
test("glop") // not found
Contemplation of that example will answer your original question, namely "I don't know what is going on here".
animals[selected] is a Optional<Optional<String>> because you're storing nil. You can:
Double unwrap your value either by using if let or ! twice.
Change the type of your dictionary to [String: String] (instead of [String: String?]), and thus avoiding nil values.
Flatten the dictionary, removing nil values, and then accessing it as a [String: String]
You can flatten the dictionary using the code in this question.
Please enclose that in bracket and use double unwrapping. try this : -
animalsToReturn.append("\((animals[selected])!!)")
func addAnimal(_ animal: String) {
guard let animal = animals[animal] else {
print("No pair")
return
}
animalsToReturn.append(animal ?? "")
}

How to safely wrap optional values in Swift? [duplicate]

How do you properly unwrap both normal and implicit optionals?
There seems to be confusion in this topic and I would just like to have a reference for all of the ways and how they are useful.
There are currently two ways to create optionals:
var optionalString: String?
var implicitOptionalString: String!
What are all the ways to unwrap both? Also, what is the difference between using ! and ? during the unwrapping?
There are many similarities and just a handful of differences.
(Regular) Optionals
Declaration: var opt: Type?
Unsafely unwrapping: let x = opt!.property // error if opt is nil
Safely testing existence : if opt != nil { ... someFunc(opt!) ... } // no error
Safely unwrapping via binding: if let x = opt { ... someFunc(x) ... } // no error
Using new shorthand: if let opt { ... someFunc(opt) ... } // no error
Safely chaining: var x = opt?.property // x is also Optional, by extension
Safely coalescing nil values: var x = opt ?? nonOpt
Implicitly Unwrapped Optionals
Declaration: var opt: Type!
Unsafely unwrapping (implicit): let x = opt.property // error if opt is nil
Unsafely unwrapping via assignment:
let nonOpt: Type = opt // error if opt is nil
Unsafely unwrapping via parameter passing:
func someFunc(nonOpt: Type) ... someFunc(opt) // error if opt is nil
Safely testing existence: if opt != nil { ... someFunc(opt) ... } // no error
Safely chaining: var x = opt?.property // x is also Optional, by extension
Safely coalescing nil values: var x = opt ?? nonOpt
Since Beta 5 we have also the new coalescing operator (??):
var a : Int?
let b : Int = a ?? 0
If the optional is != nil it is unwrapped else the value on the right of the operator is used
I created an approach to unwrap optional value:
// MARK: - Modules
import Foundation
import UIKit
import CoreData
// MARK: - PROTOCOL
protocol OptionalType { init() }
// MARK: - EXTENSIONS
extension String: OptionalType {}
extension Int: OptionalType {}
extension Double: OptionalType {}
extension Bool: OptionalType {}
extension Float: OptionalType {}
extension CGFloat: OptionalType {}
extension CGRect: OptionalType {}
extension UIImage: OptionalType {}
extension IndexPath: OptionalType {}
extension Date: OptionalType {}
extension UIFont: OptionalType {}
extension UIColor: OptionalType {}
extension UIViewController: OptionalType {}
extension UIView: OptionalType {}
extension NSMutableDictionary: OptionalType {}
extension NSMutableArray: OptionalType {}
extension NSMutableSet: OptionalType {}
extension NSEntityDescription: OptionalType {}
extension Int64: OptionalType {}
extension CGPoint: OptionalType {}
extension Data: OptionalType {}
extension NSManagedObjectContext: OptionalType {}
prefix operator ?*
//unwrapping values
prefix func ?*<T: OptionalType>( value: T?) -> T {
guard let validValue = value else { return T() }
return validValue
}
You can add your custom data type also.
Usage:-
var myString = ?*str
Hope it helps :)
An optional type means that the variable might be nil.
Example:
var myString: Int? = 55
myString = nil
The question mark indicates it might have nil value.
But if you state like this:
var myString : Int = 55
myString = nil
It will show error.
Now to retrieve the value you need to unwrap it:
print(myString!)
But if you want to unwrap automatically:
var myString: Int! = 55
Then:
print(myString)
No need to unwrap. Hope it will help.
You can also create extensions for particular type and unwrap safely with default value. I did the following for the same :
extension Optional where Wrapped == String {
func unwrapSafely() -> String {
if let value = self {
return value
}
return ""
}
}
Code sample of Safely unwrapping using binding:
let accountNumber = account.accountNumber //optional
let accountBsb = account.branchCode //optional
var accountDetails: String = "" //non-optional
if let bsbString = account.branchCode, let accString = account.accountNumber {
accountDetails = "\(bsbString) \(accString)" //non-optional
}
Unwrap optionals safely in Swift 5.7 ⛑
Different techniques (in order of preference)
Use the right tool for the job:
Optional chaining
guard let
if let
Nil coalescing operators
There are many ways to unwrap optional values safely in Swift. My reasons for ordering the techniques in my preferences above:
We should only unwrap optionals if we truly need to. In this case, we don't need to unwrap it and can use optional chaining. e.g. let value = optional?.value
Guard statements are helpful to exit the flow early when there's a precondition. It's the cleanest solution in many cases by reducing the levels of nesting.
if let may be more readable for sequential logic. In some cases, if let is more readable than guards when we don't want to exit a function but continue with additional logic outside the unwrapping block. if let is flexible and can also be used with similar syntax as guard statements.
We can use multiple guard statements to unwrap multiple optionals before using them, or even use ,, && or || to check multiple conditionals in a single guard.
Nil coalescing operators work well to cleanly unwrap optionals with a default value: ??. Don't overuse them though because using a guard is often clearer to exit early.
I've outlined the improved syntax for if let and guard let (much cleaner in Swift 5.7).
Force unwrapping or IUOs (Implicity Unwrapped Optionals) can lead to runtime crashes. They are indicated by a ! and are an anti-pattern in iOS unless part of a tests suite because they can crash if the optional is nil. In this case, we aren't leveraging Swift's improved type system over Objective-C. In tests, we don't care about clean code because the tests won't run in production and their purpose is contained.
New syntax for if let and guard
var x: EnumExample?
if let x {
print(x.rawValue) // No longer optional
}
// We can still explicitly name the `if let` value if we want.
if let value = x {
print(value.rawValue)
}
guard let x else {
return
}
print(x.rawValue) // No longer optional
guard let value = x else {
return
}
print(value.rawValue)
print(x?.rawValue ?? 0) // Unwrap with nil coalescing
NOTE: I also find Optional chaining a clean alternative to unwrapping optionals, and using x != nil sufficient for instances where we only need to check for existence. This is out of scope of the question for unwrapping optionals though.
There is only seven ways to unwrap an optional in Swift
var x : String? = "Test"
1,Forced unwrapping — unsafe.
let a:String = x!
2,Implicitly unwrapped variable declaration — unsafe in many cases.
var a = x!
3,Optional binding — safe.
if let a = x {
print("x was successfully unwrapped and is = \(a)")
}
4,Optional chaining — safe.
let a = x?.count
5,Nil coalescing operator — safe.
let a = x ?? ""
6,Guard statement — safe.
guard let a = x else {
return
}
7,Optional pattern — safe.
if case let a? = x {
print(a)
}

Resources