I have a protocol called Parameter:
protocol Parameter {
var name: String { get }
var unit: Unit? { get }
var value: Double { get }
init(name: String, unit: Unit?, value: Double)
}
I also have 16 structs that conform to Parameter:
struct Calcium: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Calcium", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Alkalinity: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Alkalinity", unit: Unit? = Unit(symbol: "ppm CaCO3"), value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Salinity: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Salinity", unit: Unit? = Unit(symbol: "SG"), value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Temperature: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Temperature", unit: Unit? = UnitTemperature.fahrenheit, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct PH: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "pH", unit: Unit? = nil, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Magnesium: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Magnesium", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Phosphate: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Phosphate", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Ammonia: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Ammonia", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Silica: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Silica", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Iodine: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Iodine", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Nitrate: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Nitrate", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Nitrite: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Nitrite", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Strontium: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Strontium", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct ORP: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "ORP", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Boron: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Boron", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
struct Iron: Parameter {
var name: String
var unit: Unit?
var value: Double
init(name: String = "Iron", unit: Unit? = UnitDispersion.partsPerMillion, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
As you can see, all of the structs implement the same initializer. In the initializer, I provide default values for two of the three parameters required by the Parameter protocol, which gives me the following initializer:
let calcium = Calcium(value: Double)
I also get the default initializer created by the structs:
let calcium = Calcium(name: String, unit: Unit?, value: Double)
When I am creating instances of the structs, both initializers appear in Xcode's code completion popover. However, I don't want the name and unit parameters to be able to be anything different than the default values provided in the initializer. I have also tried assigning default values for the name and unit properties where the they are declared inside of the struct but outside of the initializer required by the Parameter protocol.
Is there a way to initialize the structs by providing default values for the name and unit parameters, requiring only the value parameter to be provided, while not having the default initializer show in Xcode's code completion popup?
The only concern that I have with having both initializers appear in Xcode's code completion popup is that I don't want someone else creating structs and providing values other than the ones that I have provided in the initializer required by the Parameter protocol.
I realize that I could do so with a class, but I am trying to get my mind right with protocol-oriented programming and using structs.
One way to do it:
We changed all variables to optionals, and removed initializer with default parameters from protocol. If unit and value are going to have default values always, there is no need for client to see this initializer.
protocol Parameter {
var name: String? { get }
var unit: Unit? { get }
var value: Double? { get }
//init(name: String, unit: Unit?, value: Double)
init(value: Double)
}
And change structure to look like this:
struct Calcium: Parameter {
var name: String? = nil
var unit: Unit? = nil
var value: Double? = nil
init(value: Double) {
self.init(name: "Calcium", unit: UnitDispersion.partsPerMillion, value: value)
}
private init(name: String, unit: Unit, value: Double) {
self.name = name
self.unit = unit
self.value = value
}
}
In structure itself, we have added private initializer, which is called from custom initializer requiring only one parameter.
And you will have only one initializer in Xcode completion popup.

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With