reflex-frp / reflex-native

Framework for writing fully native apps using Reflex, a Functional Reactive Programming library for Haskell.
BSD 3-Clause "New" or "Revised" License
43 stars 4 forks source link
frp functional-reactive-programming haskell reactive reflex-frp

Reflex Native

Fully native apps using Reflex

Caution: This README contains forward looking statements. See the project status.

Reflex Native is a framework for writing fully native apps using Reflex, a Functional Reactive Programming library for Haskell.

It provides a cross-platform layer on top of several platform specific libraries for writing components and applications which run on iOS or Android fully native with little to no compromise in resulting app quality - that is, executing as native ARM binaries and using the platform's UI toolkit, no JavaScript runtime nor web views.

iOS prerequisites

Reflex Native UIKit and apps that use it can only be built on a Mac with Xcode installed at /Applications/Xcode.app with an iPhoneOS SDK of the version that reflex-platform expects, currently 10.2.

You can get this version by downloading Xcode 8.2.1, unpacking it, and copying

Xcode 8.2.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk

to

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk

You don't need to actually use Xcode 8.2.1, but that's the version of Xcode that has the 10.2 SDK in it.

Android prerequisites

TBD :'(

Getting started

First, see the project status for cautions about the current immature state of this project.

Building the examples for iOS

Use nix-build with the derivations under examples in default.nix, for example nix-build -A examples.ios.draggy to build examples/draggy as an iOS app. nix-build by default makes a link to the build result called result, and the apps include packaging and deployment scripts, so continuing the example you could deploy the draggy example app to an attached iPhone using result/bin/deploy <team> where <team> is your Apple developer team ID.

Building the examples for Android

TBD :'(

Using in your own project

TBD :'(

Developing Reflex Native itself

tl;dr: use make host, make android, or make ios.

Shells are provided for each of the platforms as attributes in default.nix:

You can enter each of these with nix-shell, e.g. nix-shell -A shells.ios, and then use cabal new-build to do incremental builds within the shell. cabal new-build uses a project file to determine what packages to build and any configuration overrides to use when building them, and one is provided for each platform:

So for example to do an incremental build of the iOS components:

  1. nix-shell -A shells.ios
  2. cabal --project-file=ios.project --builddir=_build/ios/dist new-build all

However as a development environment this leaves some things to be desired:

So, a Makefile is provided with targets for each platform which also builds each shell once and caches the environment.

Make targets:

Cross-platform

Reflex Native provides a cross-platform view building abstraction which allows components to be written once and operate identically across the supported platforms. This abstraction is intentionally conservative; any functionality which can't be equally supported should not be in the cross-platform abstraction.

Any substantial app requires some amount of platform-specific behavior, such as varying navigation, platform-specific functionality or libraries, or specializations to fit the platform's native look and feel. To that end, Reflex Native is intended to provide the cross-platform tools to write components that work everywhere but the overall app is intended to be platform-specific and reuse the cross-platform components.

Using a combination of platform-specific code, cross-platform code, and Haskell's excellent features for reuse you can assemble an app with maximum code sharing among platforms while avoiding the uncanny valley of cross-platform apps; views created either using the platform-specific reflex-native-* or cross-platform reflex-native packages create and maintain actual platform views and not simulacrums, and the platform-specific code you write can complete the product.

Project status

This project is in its very early stages and is probably not suitable for building a production application on immediately. In particular:

It is being open sourced early in order to foster community involvement or in the hopes that it will be useful, and is still under active development. If you're interested in building an application using it, please contribute! We're actively soliciting volunteers to work on it and make it better.

As it's in active development this README talks about intended features as if they exist, most notably Android support.