Scenario:
I want to have different types of Bonds which has a minimum value, flexi interest current bond worth(calculated on basis of some logic) and bond growth prediction.
Whenever bond value goes more than minimum value, then the growth prediction becomes appreciating and depreciating in vice versa.
I am trying to use property wrappers for the same so that I do not replicate the same behaviour for every bond:
@propertyWrapper
struct BondValue {
private var bondCurrentWorth: Int
private var minimumValue: Int
private var flexiInterest: Int
var projectedValue: BondGrowth = .appreciating // The projected value projects the growth for the bond
var wrappedValue: Int {
get {
return bondCurrentWorth
}
set {
bondCurrentWorth = newValue + (newValue * flexiInterest/100)
projectedValue = bondCurrentWorth < minimumValue ? .depriciating : .appreciating
}
}
init(wrappedValue: Int = 0, minimumValue: Int, flexiInterest: Int, value: Int) {
self.minimumValue = minimumValue
self.flexiInterest = flexiInterest
self.bondCurrentWorth = value
}
}
No for creating any bond, I do:
struct FoodBond {
var bondName: String
@BondValue(minimumValue: 200, flexiInterest: 30, value: 200) var value = 30
init(bondName: String, minimumValue: Int, flexiInterest: Int, value: Int) {
self.bondName = bondName
}
}
Problem statement: - I am not able to initialise the bondvalue with dynamic values.
Possible workaround: I would use the same approach as a normal struct in the below implementation. Though this way of using property wrapper is also specified in the docs, but I would loose the syntactic flavour of the property wrappers.
You could write code that uses the behavior of a property wrapper, without taking advantage of the special attribute syntax. For example, here’s a version of SmallRectangle from the previous code listing that wraps its properties in the TwelveOrLess structure explicitly, instead of writing @TwelveOrLess as an attribute
@propertyWrapper
struct BondValue {
private (set) var bondCurrentWorth: Int
private (set) var minimumValue: Int
private (set) var flexiInterest: Int
var projectedValue: BondGrowth = .appreciating // The projected value projects the growth for the bond
var wrappedValue: Int { .... }
init(wrappedValue: Int = 0, minimumValue: Int, flexiInterest: Int, value: Int) { ... }
}
struct FoodBond {
var bondName: String
var value = BondValue(minimumValue: 0, flexiInterest: 0, value: 0) // Provide a default value
init(bondName: String, minimumValue: Int, flexiInterest: Int, value: Int) {
self.bondName = bondName
self.value = BondValue(minimumValue: minimumValue, flexiInterest: flexiInterest, value: value)
}
}
var foodBond = FoodBond(bondName: "Food Bond", minimumValue: 200, flexiInterest: 10, value: 200)
print("Initial bond current worth - \(foodBond.value.bondCurrentWorth)")
print("Bond growth - \(foodBond.value.projectedValue)")
Any suggestions will be really helpful.
To make our wrapper configurable, we need to add all configuration parameters through an initializer. If the initializer contains a wrappedValue attribute (the initial value of our property), it must be the first parameter.
A property wrapper adds a layer of separation between code that manages how a property is stored and the code that defines a property. For example, if you have properties that provide thread-safety checks or store their underlying data in a database, you have to write that code on every property.
Property observers observe and respond to changes in a property's value. Property observers are called every time a property's value is set, even if the new value is the same as the property's current value .
@Published is one of the property wrappers in SwiftUI that allows us to trigger a view redraw whenever changes occur. You can use the wrapper combined with the ObservableObject protocol, but you can also use it within regular classes.
Referring to the section Memberwise Initialisers from Swift proposal doc for property wrappers:
Instance properties that have a property wrapper will have a corresponding parameter in the memberwise initializer, whose type will either be the original property type or the wrapper type, depending on the wrapper type and the initial value (if provided).
Solution:
struct FoodBond {
var bondName: String
@BondValue(minimumValue: 0, flexiInterest: 0, value: 0) var bondValue = 0
init(bondName: String, minimumValue: Int, flexiInterest: Int, value: Int) {
self.bondName = bondName
_bondValue = BondValue(minimumValue: minimumValue, flexiInterest: flexiInterest, value: value)
}
}
You can use the property wrapper without params and give it the type of the wrapped value, then create it in the init with your params:
struct FoodBond {
var bondName: String
@BondValue var bondValue : Int
init(bondName: String, minimumValue: Int, flexiInterest: Int, value: Int) {
self.bondName = bondName
_bondValue = BondValue(minimumValue: minimumValue, flexiInterest: flexiInterest, value: value)
}
}
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