I am writing an app in swift the connects to and stores a reference to a Bluetooth device. This Bluetooth device physically connects to a sensor (e.g., UV sensor, temperature sensor, etc.) and transmits the sensor’s readings to the app.
I have a class called Sensor that has several subclasses for each type of sensor that can be plugged into the Bluetooth device. Since the user can unplug and plug in a different sensor to this Bluetooth device, I create a new instance of my subclass depending on the sensor type and I replace the old sensor class instance with this new one. However, I haven't found a good method for copying over some of the pertinent properties that will still apply to the new sensor (I don't want all the properties copied over since some of them get set specifically depending on class whereas others will carry over regardless of which sensor is plugged into the bluetooth device).
public class Sensor {
// Properties I don’t want copied over to new class instance
public let peripheral: CBPeripheral
var sensorID: Int
var sensorImage: UIImage
var modelName: String
var sensorType: String
// Properties I do want copied over to new class instance
var bluetoothDeviceSerialNumber: String
var hardwareVersion: String
var firmwareVersion: String
var softwareVersion: String
var alias: String
var lastConnectedDate: Date
var exampleProperty1: Int
var exampleProperty2: Int
var exampleProperty3: Int
var exampleProperty4: Bool
var exampleProperty5: Bool
required public init(withPeripheral peripheral: CBPeripheral) {
self.peripheral = peripheral
}
}
class UV_Sensor: Sensor {
required public init(withPeripheral peripheral: CBPeripheral){
super.init(withPeripheral: peripheral)
var sensorID = 1
var sensorImage = UIImage(named: “UV_Sensor”)
var modelName = “UVSensorModelName”
var sensorType = “UV”
}
}
Class TemperatureSensor: Sensor {
required public init(withPeripheral peripheral: CBPeripheral){
super.init(withPeripheral: peripheral)
var sensorID = 2
var sensorImage = UIImage(named: “Temp_Sensor”)
var modelName = “TemperatureSensorModelName”
var sensorType = “Temp”
}
}
My current solution has been to have a method that manually copies over exactly the variables that I want.
func copyPropertyValues(from oldSensor: Sensor) {
self.bluetoothDeviceSerialNumber = oldSensor.bluetoothDeviceSerialNumber
self.hardwareVersion = oldSensor.hardwareVersion
self.firmwareVersion = oldSensor.firmwareVersion
self.softwareVersion = oldSensor.softwareVersion
self.alias = oldSensor.alias
self.lastConnectedDate = oldSensor.lastConnectedDate
self.exampleProperty1 = oldSensor.exampleProperty1
self.exampleProperty2 = oldSensor.exampleProperty2
self.exampleProperty3 = oldSensor.exampleProperty3
self.exampleProperty4 = oldSensor.exampleProperty4
self.exampleProperty5 = oldSensor.exampleProperty5
}
I'm not a fan of this idea because it doesn't scale very well in my opinion and if I or some future developer adds a new property to this sensor class, they also have to remember to add it to this method. I've tried also looking at reflection as that has seemed like the most promising method but have not had much success getting anything close to achieving what I want.
You've already made two groupings of properties here, with your comments and use of white space:
public class Sensor {
// Properties I don’t want copied over to new class instance
public let peripheral: CBPeripheral
// ... group 1
// Properties I do want copied over to new class instance
var bluetoothDeviceSerialNumber: String
// ... group 2
Groupings like this are structs screaming to get out. You might try something like this:
public class Sensor {
struct SensorDetails {
var bluetoothDeviceSerialNumber: String
var hardwareVersion: String
var firmwareVersion: String
var softwareVersion: String
var alias: String
var lastConnectedDate: Date
var exampleProperty1: Int
var exampleProperty2: Int
var exampleProperty3: Int
var exampleProperty4: Bool
var exampleProperty5: Bool
}
// Properties I don’t want copied over to new class instance
public let peripheral: CBPeripheral
var sensorID: Int
var sensorImage: UIImage
var modelName: String
var sensorType: String
// Properties I do want copied over to new class instance
var sensorDeatils: SensorDetails
required public init(withPeripheral peripheral: CBPeripheral) {
self.peripheral = peripheral
}
}
Now your copyPropertyValues
function becomes trivial:
func copyPropertyValues(from oldSensor: Sensor) {
self.sensorDetails = oldSensor.sensorDetails
}