Converting Firebase .value to NSDecimal - Swift

238 Views Asked by At

I am a new Swift developer. I am using Swift 4.2 and Xcode 10.1.

I need to pull a number from firebase that represents dollars and cents (e.g., 10.20) and add to that number, divide that number, etc. The result should always have two numbers after the decimal.

I am attempting to use NSDecimalNumber, but I get errors in converting.

Here's my code. addend is of type NSDecimalNumber.

dbRef.observeSingleEvent(of: .value) { (snapshot) in

    // Get the balance
    let NSbalance = snapshot.value as! NSDecimalNumber
    // Add the addend
    let balance = NSbalance + addend
    // Set the new balance in the database and in the user defaults
            dbRef.setValue(balance)
            defaults.set(balance, forKey: Constants.LocalStorage.storedBalance)
}

I am getting the error Cannot convert value of type 'NSDecimalNumber' to expected argument type 'Self'. When I take its suggestion and make the following change: Replace 'NSbalance' with 'Self(rawValue: Self.RawValue(NSbalance)) I get "use of unresolved identifier Self."

Should I use NSDecimalNumber for this purpose? If not, what should I do?

1

There are 1 best solutions below

0
TM Lynch On BEST ANSWER

The solution is to use Double for the type. A .value from Firebase Realtime Database are type NSNumber if the value is a number (not a string), so I can cast as a Double easily. Although Double does not have the accuracy of Decimal for base-10 calculations, it is more than accurate for the low-level currency values I'm using, which always have only two numbers after the decimal. Then I use a number formatter to format as currency and eliminate the extra digits after the decimal. The code that works is below:

This code is in the service that adds the amount to increase the balance:

dbRef.observeSingleEvent(of: .value) { (snapshot) in

// Get the snapshot value
    let NSbalance = snapshot.value as! Double

    // Add the addend
    let balance = NSbalance + addend

    // Set the new balance in the database and in the user defaults
    dbRef.setValue(balance)
    defaults.set(balance, forKey: Constants.LocalStorage.storedBalance)

This code is in the view controller that shows the balance:

 dbRef.observe(.value) { (snapshot) in
     //Get the balance
     self.balance = snapshot.value as! Double
     // Format the balance
     let currencyFormatter = NumberFormatter()
     currencyFormatter.numberStyle = .currency
     let balanceString = currencyFormatter.string(from: self.balance as NSNumber)
            self.balanceLabel.setTitle(balanceString, for: .normal)
 }