DEV Community

Adam Bennett
Adam Bennett

Posted on

Conditional statements in Builders in Kotlin

At Blockchain, we recently updated our Android app to use more robust push notifications via FCM, notifying users of BTC received to their wallets. 

As you might expect, we added a custom vibration pattern to our notifications, but this presented a slight problem. As it turns out, devices where Android ≤4.3 will throw an errant SecurityException: Requires VIBRATE permission. This is easily fixed, but how do we do this in an idiomatic way?

One suggestion was to try/catch firing the notification — this is obviously quite nasty and is a raw deal for users on old devices. The simple way would be to this would be to turn the builder into a local val and then simply amend the builder separately:

This is absolutely fine but it breaks up the Builder pattern and we can do better. What if we could put this logic in-line?

Using extension functions, we can extend NotificationCompat.Builder and create a new function that accepts a predicate, and calls either one function or another depending on the outcome. Taking advantage of function literals with receivers (ie, A.() -> A), we can ensure that the functions to be triggered are both existing public methods of NotificationCompat.Builder and return the NotificationCompat.Builder object itself.

This allows us to do this:

Much cleaner, and doesn’t break the Builder flow. This ternary function seems pretty useful, can we generify it for use with any Builder class? Of course:

So this worked great and I felt pretty good about it for about 15 minutes, and then I realised that infact, Kotlin already had me covered:

apply is in-fact what exactly I was looking for, as this is both it’s receiver and return type. Sheepishly, I corrected my fun-but-not-idiomatic code and pushed it to origin.

Still, this was a fun learning experience that I thought I’d share. Kotlin and it’s high-order functions, including those built-in, are incredibly powerful and I love finding new applications for them.

Top comments (1)

Collapse
 
crosdev profile image
José Martínez

Ooohh, wow. It's very useful. I'll to update my code xD.

Thanks for sharing.