swiftnsdecimalnumber

Converting Firebase .value to NSDecimal - Swift


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?


Solution

  • 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)
     }