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 ?
2
Answers
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
If Let Unwrapping
Default Value Unwrapping
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.
There is no "one line" solution, but you can use
KeyPath
s to reduce the series ofif 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.Use an extension to create a default implementation of the
parameters()
function, as the code will be the same for allParameterable
s. It iterates over the dictionary entries and uses the associatedKeyPath
to access the relevant property and put it in the output dictionary. If a given property isnil
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]
)Use this protocol to create a
DoctorsFilter
implementation:The other approach is to simply split your creation of the
parameters
dictionary into multiple lines; If you assignnil
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)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 aPartialKeyPath
returns a double optional. This needs to be handled.