Search code examples
iosnsdecimalnumber

NSDecimalNumber math operation causes app to crash when UITextField includes currency symbol


I am using the following code to try and do simple math operations based on two text fields. The issue is that the text field has the currency symbol in them and it causes NSDecimalNumber to crash, if I have the text fields without the currency symbol in the strings it works fine.

I tried adding a second currencyFormatter to set the currency to blank but I cannot figure out how to utilise it.

- (IBAction)transactionDetailViewQtyTxt_EditDidEnd:(id)sender {
    NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];
    [currencyFormatter setNumberStyle: NSNumberFormatterCurrencyStyle];
    [currencyFormatter setCurrencySymbol:[NWTillHelper getCurrencySymbol]];

    NSNumberFormatter *currencyFormatter2 = [[NSNumberFormatter alloc] init];
    [currencyFormatter2 setNumberStyle: NSNumberFormatterDecimalStyle];
    [currencyFormatter2 setCurrencySymbol:@""];

    _transactionDetailViewSumTxt.text = [currencyFormatter stringFromNumber:[[NSDecimalNumber decimalNumberWithString:_transactionDetailViewPriceTxt.text] decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithString:_transactionDetailViewQtytxt.text]]];
}

Crash log below

2016-11-30 21:17:37.913 NWMobileTill[2048:52396] *** Terminating app due to uncaught exception 'NSDecimalNumberOverflowException', reason: 'NSDecimalNumber overflow exception'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e26234b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010d8a621e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010e2cb265 +[NSException raise:format:] + 197
    3   Foundation                          0x000000010d4d0917 -[NSDecimalNumberHandler exceptionDuringOperation:error:leftOperand:rightOperand:] + 193
    4   Foundation                          0x000000010d4cf761 _checkErrorAndRound + 65
    5   Foundation                          0x000000010d4cfa31 -[NSDecimalNumber decimalNumberByMultiplyingBy:withBehavior:] + 159
    6   NWMobileTill                        0x000000010d28a6d8 -[TransactionDetailView transactionDetailViewQtyTxt_EditDidEnd:] + 440
    7   UIKit                               0x000000010e6875b8 -[UIApplication sendAction:to:from:forEvent:] + 83
    8   UIKit                               0x000000010e80cedd -[UIControl sendAction:to:forEvent:] + 67
    9   UIKit                               0x000000010e80d1f6 -[UIControl _sendActionsForEvents:withEvent:] + 444
    10  UIKit                               0x000000010f19a6f8 -[UITextField _resignFirstResponder] + 313
    11  UIKit                               0x000000010e89d054 -[UIResponder _finishResignFirstResponder] + 286
    12  UIKit                               0x000000010f19a4e6 -[UITextField _finishResignFirstResponder] + 49
    13  UIKit                               0x000000010e89d103 -[UIResponder resignFirstResponder] + 140
    14  UIKit                               0x000000010f19a3b5 -[UITextField resignFirstResponder] + 136
    15  UIKit                               0x000000010e89cd93 -[UIResponder becomeFirstResponder] + 358
    16  UIKit                               0x000000010e736151 -[UIView(Hierarchy) becomeFirstResponder] + 138
    17  UIKit                               0x000000010f199280 -[UITextField becomeFirstResponder] + 51
    18  UIKit                               0x000000010ebd695f -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] + 206
    19  UIKit                               0x000000010ebda177 -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) oneFingerTap:] + 3823
    20  UIKit                               0x000000010ebc7e41 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 57
    21  UIKit                               0x000000010ebcfbe0 _UIGestureRecognizerSendTargetActions + 109
    22  UIKit                               0x000000010ebcd6af _UIGestureRecognizerSendActions + 227
    23  UIKit                               0x000000010ebcc93b -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 891
    24  UIKit                               0x000000010ebb8a0e _UIGestureEnvironmentUpdate + 1395
    25  UIKit                               0x000000010ebb8453 -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 521
    26  UIKit                               0x000000010ebb7636 -[UIGestureEnvironment _updateGesturesForEvent:window:] + 286
    27  UIKit                               0x000000010e6f63b9 -[UIWindow sendEvent:] + 3989
    28  UIKit                               0x000000010e6a363f -[UIApplication sendEvent:] + 371
    29  UIKit                               0x000000010ee9571d __dispatchPreprocessedEventFromEventQueue + 3248
    30  UIKit                               0x000000010ee8e3c7 __handleEventQueue + 4879
    31  CoreFoundation                      0x000000010e207311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    32  CoreFoundation                      0x000000010e1ec59c __CFRunLoopDoSources0 + 556
    33  CoreFoundation                      0x000000010e1eba86 __CFRunLoopRun + 918
    34  CoreFoundation                      0x000000010e1eb494 CFRunLoopRunSpecific + 420
    35  GraphicsServices                    0x0000000112512a6f GSEventRunModal + 161
    36  UIKit                               0x000000010e685964 UIApplicationMain + 159
    37  NWMobileTill                        0x000000010d28869f main + 111
    38  libdyld.dylib                       0x000000011042d68d start + 1
    39  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Solution

  • Why not just strip out the currency symbol first?

    NSString * numberNoCurrency = [_transactionDetailViewPriceTxt.text stringByReplacingOccurrencesOfString:@"$" withString:@""];
    

    then feed that string to your decimal conversion for the multiply.