1 _app.nit_, a framework for portable applications
3 The framework provides services to manage common needs of modern mobile applications:
10 * Compilation and packaging
12 The features offered by _app.nit_ are common to all platforms, but
13 may not be available on all devices.
15 # Application Life-Cycle
17 The _app.nit_ application life-cycle is compatible with all target platforms.
18 It relies on the following sequence of events, represented here by their callback method name:
20 1. `on_create`: The application is being created.
21 You should build the UI at this time and launch services.
23 2. `on_resume`: The app enters the active state, it is in the foreground and interactive.
25 3. `on_pause`: The app becomes inactive and it leaves the foreground.
26 It may still be visible in the background.
28 4. `on_stop`: The app is completely hidden.
29 It may then be destroyed (without warning) or go back to the active state with `on_restart`.
31 5. `on_restart`: The app goes back to the inactive state.
32 You can revert what was done by `on_stop`.
34 ![_app.nit_ life-cycle](doc/app-nit-lifecycle.png)
36 Life-cycle events related to saving and restoring the application state are provided by two special callback methods:
38 * `on_save_state`: The app may be destroyed soon, save its state for a future `on_restore_state`.
39 There is more on how it can be done in the `app::data_store` section.
41 * `on_restore_state`: The app is launching, restore its state from a previous `on_save_state`.
43 These events are synchronized to the native platforms applications
44 The `App` instance is the first to be notified of these events.
45 Other UI elements, from the `ui` submodule, are notified of the same events using a simple depth first visit.
46 So all UI elements can react separately to live-cycle events.
50 The `app::ui` module defines an abstract API to build a portable graphical application.
51 The API is composed of interactive `Control`s, visible `View`s and an active `Window`.
53 Here is a subset of the most useful controls and views:
55 * The classic pushable `Button` with text (usually rectangular).
57 * `TextInput` is a field for the user to enter text.
59 * `HorizontalLayout` and `VerticalLayout` organize other controls in order.
61 Each control is notified of input events by callbacks to `on_event`.
62 All controls have observers that are also notified of the events.
63 So there is two ways to customize the behavior on a given event:
65 * Create a subclass of the wanted `Control`, let's say `Button`, and specialize `on_event`.
67 * Add an observer to a `Button` instance, and implement `on_event` in the observer.
71 The example at `examples/ui_example.nit` shows off most features of `app::ui` in a minimal program.
72 You can also take a look at the calculator (`../../examples/calculator/src/calculator.nit`) which is a concrete usage example.
74 ## Platform-specific UI
76 You can go beyond the portable UI API of _app.nit_ by using the natives services of a platform.
78 The suggested approach is to use platform specific modules to customize the application on a precise platform.
79 See the calculator example for an adaptation of the UI on Android,
80 the interesting module is in this repository at ../../examples/calculator/src/android_calculator.nit
82 # Persistent State with data\_store
84 _app.nit_ offers the submodule `app::data_store` to easily save the application state and user preferences.
85 The service is accessible by the method `App::data_store`. The `DataStore` itself defines 2 methods:
87 * `DataStore::[]=` saves and associates any serializable instances to a `String` key.
88 Pass `null` to clear the value associated to a key.
90 * `DataStore::[]` returns the object associated to a `String` key.
91 It returns `null` if nothing is associated to the key.
96 import app::data_store
101 redef fun on_save_state
103 app.data_store["first run"] = false
104 app.data_store["user name"] = user_name
106 super # call `on_save_state` on all attached instances of `AppComponent`
109 redef fun on_restore_state
111 var first_run = app.data_store["first run"]
112 if first_run != true then
113 print "It's the first run of this application"
116 var user_name = app.data_store["user name"]
117 if user_name isa String then
118 self.user_name = user_name
119 else self.user_name = "Undefined"
128 The module `app::http_request` provides services to execute asynchronous HTTP request.
129 The class `AsyncHttpRequest` hides the complex parallel logic and
130 lets the user implement methods acting only on the UI thread.
131 See the documentation of `AsyncHttpRequest` for more information and
132 the full example at `examples/http_request_example.nit`.
134 # Metadata annotations
136 The _app.nit_ framework defines three annotations to customize the application package.
138 * `app_name` takes a single argument, the visible name of the application.
139 This name is used for launchers and window title.
140 By default, the name of the target module.
142 * `app_namespace` specifies the full namespace (or package name) of the application package.
143 This value usually identify the application uniquely on application stores.
144 It should not change once the application has benn published.
145 By default, the namespace is `org.nitlanguage.{module_name}`.
147 * `app_version` specifies the version of the application package.
148 This annotation expects at least one argument, usually we use three version numbers:
149 the major, minor and revision.
150 The special function `git_revision` will use the prefix of the hash of the latest git commit.
151 By default, the version is 0.1.
153 * `app_files` tells the compiler where to find platform specific resource files associated to a module.
154 By default, only the root of the project is searched for the folders `android` and `ios`.
155 The `android` folder is used as base for the generated Android project,
156 it can be used to specify the resource files, libs and even Java source files.
157 The `ios` folder is searched for icons only.
159 Each argument of `app_files` is a relative path to a folder containing extra `android` or `ios` folders.
160 If there is no arguments, the parent folder of the annotated module is used.
161 In case of name conflicts in the resource files, the files from the project root have the lowest priority,
162 those associated to modules lower in the importation hierarchy have higher priority.
169 app_namespace "org.example.my_app"
170 app_version(1, 0, git_revision)
174 # Compiling and Packaging an Application
176 The Nit compiler detects the target platform from the importations and generates the appropriate application format and package.
178 Applications using only the portable services of _app.nit_ require some special care at compilation.
179 Such an application, let's say `calculator.nit`, does not depend on a specific platform and use the portable UI.
180 The target platform must be specified to the compiler for it to produce the correct application package.
181 There is two main ways to achieve this goal:
183 * The mixin option (`-m module`) imports an additional module before compiling.
184 It can be used to load platform specific implementations of the _app.nit_ portable UI.
187 # GNU/Linux version, using GTK
188 nitc calculator.nit -m linux
191 nitc calculator.nit -m android
194 nitc calculator.nit -m ios
197 * A common alternative for larger projects is to use platform specific modules.
198 Continuing with the calculator example, it is adapted for Android by the module `android_calculator.nit`.
199 This module imports both `calculator` and `android`, it can then use Android specific code.
202 module android_calculator