JSON and decimal values

In this short post I will explain why floating point or large decimal values should be represented as strings when transferring data using JSON. This post is based on my recent discovery when trying to fix a nasty bug, when running my app on iOS 11 beta3.

Let’s assume that we have a simple JSON representation, containing a large decimal value. Let it be 79228162514264337593543950335, which is Decimal.MaxValue (in C#)

{
"data": 79228162514264337593543950335
}

If you want to parse this on iOS 11 beta 3 you will get:

which surprisingly returns a rounded result:

79228162514264340000000000000

When you send this again to some C# backend, you will probably get a parsing error as this number is larger than Decimal.MaxValue.

What may surprise you, this works perfectly on iOS 10:

It looks like between iOS 10 and 11, JSONSerialization, under the hood, started to use directly NSNumber instead of NSDecimalNumberPlaceholder. NSNumber cannot represent such a big number and the result is not correct.

Hence, if you want to pass a large number in JSON or if precision is of importance, values should be passed as strings.

AFAIK, in JSON numeric precision is not specified and each parser may choose whatever is convenient. If precision is important you should always pass numeric values as strings and convert them to appropriate representation in your client application.

If you enjoyed this short post, please follow me on twitter: @tgebarowski

Many thanks to Pawel Kowalczuk @riamf1, for his contribution to this post.

Closures argument + member function = retain cycle?

After introducing ARC memory management was simplified a lot, but still could not be forgotten. For sure every developer working with either Objective-C or Swift had to deal with retain cycles. There are lots of in depth posts about this topic and I do not want to rephrase them, so instead I will link to my favourite from krakendev. Unfortunately this post does not cover everything and I would like to mention some specific case which I encountered not that long ago.

Imagine following example, where private member function is passed as a closure argument:

The problem with the above code is that sendRequest returns its result using @escaping closure from a background queue.
Passing a private handleResponse function as a closure argument creates a retain cycle, hence deinit is never called on Dispatcher object.

The problem could be easily solved by either:

  • inlineing handleResponse content withing the closure where self is weak/unowned
  • wrapping handleResponse with another closure where self is weak/unowned

The above code looks ugly and is less compact. What if we created a helper function allowing us to wrap up this code?

and then use the following code?

Not perfect, but definitely more compact. Anyway, I think that this is something that could be addressed in new version of Swift.

Check out my GitHub project with Swift One-Liners, where you can find this exemplary wrapper, extended with versions having different closure signatures.

If you enjoyed this article, please follow me on twitter: @tgebarowski

SwiftySettings

For the last two¬†weeks I’ve been busy doing my side project, a library helping building in-app settings for iPad and iPhone apps.

By providing a declarative DSL, SwiftySettings allows to define your own settings, integrate with storage interface and automatically generate native Settings app like user interface.

Read More