TL;DR available at the bottom of the post.
“A React Native App is a Real Mobile App”
With React Native, you don’t build a “mobile web app”, an “HTML5 app”, or a “hybrid app”. You build a real mobile app that’s indistinguishable from an app built using Objective-C or Java. React Native uses the same fundamental UI building blocks as regular iOS and Android apps. You just put those building blocks together using JavaScript and React. [project site]
That doesn’t sound too bad, but why do we have to do it in JavaScript?
Well, this article shows that we don’t have to.
The nightwatch app
Consider you are working for some kind of Nightwatch and it’s getting dark and your watch is about to begin.
The nice people of your order gave you a phone and a new app. At the beginning of the night it downloads a list with locations that you have to check. Every location can be marked as OK or you can blow a virtual horn to trigger an alarm. The app also allows you to append an photo of the situation on the ground.
Since many of the locations that you will visit are far away from good internet connection the app stores everything locally on your phone. Once in a while it will sync with the nightwatch central.
So this could look a bit like this:
So now after embaressing myself and showing my design skills, let’s jump into the technical stuff.
Developing with F# in VS Code
The app was developed with F# in Visual Studio Code (with ionide and react native plugins). This development environment runs on all platforms, so you can use Windows, Linux or your Mac.
As you can see we have a React Native app with automatic loading of compiled F# code.
The big difference to using JavaScript is that everything is statically typed – even the access to the JavaScript APIs. This gives you nice autocomplete features and depending on the concrete bindings you can even get documentation in the editor:
Krzysztof CieÅ›lak did really amazing work with the Ionide – this tooling works pretty well. Take a look at his blog to find out more about the awesomeness that he brings to the ecosystem. He also played an important part in getting React Native to work with F#.
Introducing Fable
Fable is the most important technology behind all of this. It was designed by Alfonso Garcia-Caro as a F# to JavaScript compiler and can do real magic in the browser. Take the time and watch the 10min intro. I can’t stress enough how well this open source project is managed. It’s a real pleasure to be part of it now.
In our case it bridges React Native APIs into F# and also compiles the F# code back to JavaScript whenever we save a file. The React Native framework is listening for the changes in the JavaScript files and swaps the code in the device simulator. There is a lot going on behind the scenes, but it’s already working surprisingly well.
Using JavaScript APIs
Since most of the React Native APIs are developed in JavaScript it’s important to bring these APIs over to F#. This is done as a community effort and the Fable project creates typed JavaScript bindings for many major JavaScript frameworks. This effort is comparable to DefinitelyTyped in the TypeScript world. There is even a tool that can help to convert TypeScript bindings to Fable bindings.
In our case the fable-import-react-native is the most important package. It provides typed bindings to most of the React Native APIs.
This snippet creates a View component in React Native and puts two buttons inside it.
Using F#
One nice benefit of this model is that we can use ordinary, statically typed F# code for our app. In the demo project you can find a small F# domain model:
If you are interested in learning the language then I recommend to look at website of the F# software foundation. For domain driven design in F# you can find excellent articles on a site called “F# for fun and profit“.
Access to native components
React Native allows you to access native phone components like the camera. Most of these APIs are written in a mix of Java/ObjectiveC and JavaScript. Given the Fable bindings are already present it’s super easy to access the same APIs from F#. In the following sample we access a nice ImagePicker via the fable-import-react-native-image-picker bindings:
This ImagePicker is distributed via a separate npm package, but it’s API feels like the rest of the React Native functions. We can provide some properties and a callback – and everything is statically typed so that we have autocompletion in VS Code.
Data storage
For most apps you want to have some local storage in order to cache information. React Native provides a basic abstraction called AsyncStorage that works on Android and iOS. With the help of a package called fable-react-native-simple-store we can use it from F#:
As you can see all function in this storage model are asynchronous and with the help of the async computation expressions they become really easy to use in F#.
Web access
Another advantage of React Native is the huge ecosystem you see on npm. In our app we want to retrieve a list with locations that we need to check. This list is just a bit of JSON on a http resource. With the help of a very popular JavaScript package called fetch and the corresponding fetch-bindings (written by Dave Thomas) we can write something like this:
So we see the same async model here and everything fits nicely together.
Project status
The project with the working title “Fable |> React Native” is currently considered “highly experimental”. APIs and JavaScript bindings are not complete and likely to break multiple times.
In general the Fable project is shaping things up for a v1.0 release. So sharing experiences, comments and bug reports with the Fable compiler and APIs is appreciated.
Debugging of the react native apps is currently only working in the generated JavaScript. With the next release of the VS Code react native extension we will probably be able to set breakpoints directly in the F# source.
That said, it already feels very very productive and if you are interested in this kind of mobile development then check out the sample project and follow how it develops over time. There is even a similar approach that allows you to use F# on fuse, so I think we will probably see a lot of choice in the future.
TL;DR for F# devs
With this model you can start to develop Android and iOS apps on the react native model while still keeping most of the type safety and tooling. Using fable gives you access to a huge ecosystem with JavaScript libraries and frameworks. Check out the sample project and follow the instructions in the Readme.
TL;DR for JavaScript devs
If you like creating apps with the React Native model, but it always felt a bit hard to maintain JavaScript, then this might be interesting for you. With this approach you can apply all your knowledge and use it from a excellent type safe language with amazing autocompleting tooling.
With one or two tricks you can even reuse many of the npm libraries that you know and love. Check out the sample project and follow the instructions in the Readme.
TL;DR for TypeScript devs
You have already left the path of plain JavaScript. Maybe you are ready to leave it a bit further and to investigate different languages like Elm or PureScript. If this is you then check out the sample project and follow the instructions in the Readme. It shows you how a language like F# can help you to work with JavaScript APIs.
TL;DR for C# devs
Sorry, nothing to see here.
Tags:
F#,
reacr-native,
react,
react-native
[This post my second entry of the F# advent calendar 2015 series. You can also read the first post about “Using Async.Choice in Paket“]
Recently I was asked to help with a website that was based on suave.io. The task was to transform the existing F# script based suave.io website to something that can be run in the enterprise infrastructure and also performs some background tasks like creating Excel reports recurringly.
Suave as a (windows) service
A lot of the suave.io samples work with simple .fsx script files. This approach is indeed simple and allows fast prototyping with the use of the REPL. Even more complex websites like fssnip.net are using this approach with great success (code here). One of the benefits of script based suave solutions is that they are often equipped with a FAKE build script that rebuilds the website automatically if someone changes a file. One prominent example is FsReveal:
But sometimes you want to have a “real Visual Studio project” with debugging support and your enterprise might want to install your website as a Windows service. So the first step was to convert the F# script based approach into a project and adding TopShelf layer to make it runnable as Windows service. Thanks to a short blog post by Tomas Jansson this was super easy. It’s basically just installing TopShelf.FSharp via Paket and adding a single file with the config. Look into Tomas’s blog post to see the details.
After moving to the TopShelf model we still wanted to have automatic website rebuild whenever someone touched the source code. This little FAKE script makes this possible:
Running background jobs
The website already allowed to generate Excel reports by clicking somewhere in the UI. In addition to that we wanted to create the Excel reports recurringly in background jobs. Scott Hanselman has a blog post about “How to run Background Tasks in ASP.NET” and shows a couple of solutions that while optimized for ASP.NET would probably work with suave.io as well. But in this case we wanted to have something that syncronizes with the IO of the website so we decided to use F#’s MailboxProcessor feature a.k.a. “agents”. (As always: Scott Wlaschin has a nice introduction to agents.)
As a small intro into background jobs we start with F# counter agent sample by Tomas Petricek:
This little snippet shows an agent that calculates averages of the messages that it receives. Now let’s add a background job that recurringly sends messages to the counter agent:
In order to use this we need a bit of ugly infrastructure code that we will hide in a library:
So let’s try this out in the F# interactive:
Since this works as expected we can use it in our website:
Since all the user triggered reporting will also go through this taskAgent we ensure that IO is synchronized.
Sample project
In https://github.com/forki/backgroundjobs you can find a sample project which does exactly the two points from above.
As you can see the website performs background jobs and is rebuilding/restarting automatically when a source code file is saved.
Tags:
F#,
fsadvent,
fsharp
[This post is part of the F# advent calendar 2015 series.]
Prologue: What is Paket?
Paket is a dependency manager for .NET with support for NuGet packages and GitHub repositories. It enables precise and predictable control over what packages the projects within your application reference. If you want to learn how to use Paket then read the “Getting started” tutorial and take a look at the FAQs.
Async computations in F#
Asynchronous Workflows are a very old F# feature (they already shipped in 2007) and they are used in many places in Paket. In this article I want to highlight one of the nice applications that F#’s async model allows you.
Many readers are probably familiar with C#’s async and await keywords (IIRC released with C# in 2012), but F#’s async feature works a little different. You can read more about some of “Asynchronous gotchas in C#” in Tomas Petricek’s excellent blog post. Most of these gotchas come from the fact that C# is starting all async tasks automatically while F# wraps the logic in data and allows you to run it explicitly. For a really good introduction to asynchronous programming with F# I can recommend Scott Wlaschin’s blog post.
The issue: retrieving version numbers from NuGet feeds
Paket’s package resolution algorithm (if you are interested in algorithms then read more) needs to know which versions are avalaible for a given package. Usually users specify more than one NuGet feed and different NuGet feeds support different protocols. The following code shows how older Paket versions retrieved all version numbers for a given package across all configured NuGet feeds:
As you can see getAllVersions tries 4 different NuGet protocols per source and returns the first result that is not None. Every getVersionsViaProtocol call performs async web request. In GetAllVersions we run this function for every NuGet source in parallel and combine the results. This code is very similar to the “async web downloader” sample in Scott Wlaschin’s async blog post and basically the “hello world” of asynchronous programming.Â
Code cleanup
The getAllVersions is deeply nested and it’s hard to understand what’s going on. With the help of List.tryPick we can rewrite the code as:
List.tryPick returns the first result that is not None. So instead of nesting multiple match and let! expressions we use a higher-order-function to encapsulate the same pattern.
Introducing Async.Choice
After using this code for a while in Paket we noticed that different NuGet server implementations each implement a different subset of the 4 protocols and differ very much in the response times. So there was no order of the protocols that would work good for all server implementations. But what if we could query all 4 protocols in parallel and just take the fastest response?
The change is relatively easy and we can rewrite the GetAllVersions as:Instead of running the web requests synchronously and in order we run the four web request per NuGet feed in parallel and take the first response that is not None.
Implementation of Async.Choice
Unfortunately Async.Choice is not part of the standard FSharp.Core library and it turns out it is not easy to implement. There are many different implementations floating around on the internet. The one we use in Paket is by Eirik Tsarpalis and taken from fssnip. One of the advantages of this version is that the automatic cancellation of tasks works nicely. Since we are running lots and lots of web requests in parallel and always take the first response we want to cancel all the other pending web requests. Otherwise we would basically DDOS the feeds with useless requests (and yes that happened to us ;-)). Since Async.Choice is very useful we sent a pull request to the Visual F# project and hope that one day it will be in the box.Â
Epilogue
Treating computations as data has even more advantages. The m-brace project created a new version of computation workflows called “cloud”:
cloud is a computation workflow builder and allows you to run your computations in the cloud. In contrast to async we don’t only control when something gets executed but also where. They even have a Cloud.Choice, which allows you to run tasks asynchronous in the cloud and take the first succeeding result.
Btw: async and cloud aren’t language keywords like C#’s async and await, but implemented as normal F# code in libraries. If you want to define your own computation expression builders, then the MSDN docs are a good starting point.
Tags:
async,
F#,
fsadvent,
fsharp
As many readers already know I’m maintaing the open source projects FAKE and Paket. These projects are used in many companies and open source projects to make continuous integration work on .NET and mono.
In this article series I want to highlight some of the more unsual use cases. Today I want to start and highlight the first 6 amazing projects.
FsReveal
“FsReveal allows you to write beautiful slides in Markdown and brings C# and F# to the reveal.js web presentation framework.” [project site]
FsReveal uses Paket’s GitHub file dependencies feature to download reveal.js:
It also uses a FAKE build script which converts Markdown files to html slides (via FSharp.Formatting) and runs these slides in a suave.io web server. FAKE’s file system watcher + suave’s socket implementation even allows you to edit your slides with automatic preview:
Stanford.NLP.NET
“Stanford.NLP for .NET is a port of Stanford NLP distributions to .NET.
This project contains build scripts that recompile Stanford NLP .jar packages to .NET assemblies using IKVM.NET, tests that help to be sure that recompiled packages are workable and Stanford.NLP for .NET documentation site that hosts samples for all packages. All recompiled packages are available on NuGet.” [project site]
This project downloads .jar packages via Paket’s HTTP dependencies feature, recompiles everything to .NET via IKVM.NET in a FAKE build script and republishes it on NuGet. Automatic Java to .NET compilation – how cool is that?
Paket.VisualStudio
“Manage your Paket dependencies from Visual Studio!” [project site]
Paket.VisualStudio is a VisualStudio addin that you can download from Microsoft’s VisualStudio gallery. Unfortunately even in 2015 Microsoft doesn’t provide an API for automating the upload to its gallery. Therefore Paket.VisualStudio uses Paket’s NuGet dependencies feature to download canopy and Selenium:
It then uses canopy + Selenium in a FAKE script to upload the addin via browser automation:
Ionide-F#
“It’s part of Ionide plugin suite. F# IDE-like possibilities in Atom editor” [project site]
Ionide is an Atom plugin written in F#. It’s using Paket and FAKE to automate the build and release process.
First it uses FunScript to transpile F# to Javascript and then automates npm to resolve Javascript dependencies and apm to upload the plugin to the Atom gallery.
Akka.Net
“Akka.NET is a community-driven port of the popular Java/Scala framework Akka to .NET.” [project site]
Akka.Net is a big (mainly C#) open source project that uses FAKE and Paket. One interesting observation is that it needs to create different xUnit addins and therefore uses Paket’s groups feature to maintain the xUnit versions.
FSharp.Data
“The F# Data library implements everything you need to access data in your F# applications and scripts. It implements F# type providers for working with structured file formats (CSV, HTML, JSON and XML) and for accessing the WorldBank data. It also includes helpers for parsing CSV, HTML and JSON files and for sending HTTP requests.” [project site]
One of the many interesting things in FSharp.Data’s build is that it uses Paket to retrieve the FSharp.TypeProviders.StarterPack. These files need to be included in any F# type provider project and Paket allows you to manage this easily.
Tags:
F#,
F-sharp Make
Today I released FAKE 2.12 with a lot of small bug fixes and improvements. The biggest feature is that we now use NancyFx for FAKE.Deploy. A big thanks to all of the 60 contributors.
What’s new?
- Add getDependencies to NugetHelper #373
- Add more F# friendly functions for IO.Path #374
- SourceLink support #345
- NancyFx instead of ASP.NET MVC for FAKE.Deploy #376 – big thanks to @MorganPersson
- Allows to execute processes as unit tests #379
- Allow to run MsTest test in isolation #367
- Fixed Nuget.packSymbols #366
- Fixed bug in SemVer parser #364
- New title property in Nuspec parameters #359
- Added option to disabled FAKE’s automatic process killing #357
- Better AppyVeyor integration #353, #345
- Added ability to define custom MSBuild loggers #352
- Fix for getting the branch name with Git >= 1.9 #351
- Added functions to write and delete from registry #350
- NUnit NoThread, Domain and StopOnError parameters #349
- Add support for VS2013 MSTest #346
- Lots of small fixes
Getting started
If you new to FAKE you should read the getting started guide or clone the F# ProjectScaffold.
Go and grab the bits
Feel free to contact me if you need help for the upgrade.
Tags:
F#,
Fake