diff --git a/._.DS_Store b/._.DS_Store
new file mode 100755
index 00000000..8e82ed96
Binary files /dev/null and b/._.DS_Store differ
diff --git a/.github/workflows/scrape-plugins.yml b/.github/workflows/scrape-plugins.yml
old mode 100644
new mode 100755
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/.husky/.gitignore b/.husky/.gitignore
old mode 100644
new mode 100755
diff --git a/.prettierignore b/.prettierignore
old mode 100644
new mode 100755
diff --git a/.prettierrc b/.prettierrc
old mode 100644
new mode 100755
diff --git a/.vitepress/config.js b/.vitepress/config.js
old mode 100644
new mode 100755
index 46de274d..39d2d1a1
--- a/.vitepress/config.js
+++ b/.vitepress/config.js
@@ -68,13 +68,18 @@ module.exports = {
nav: [
{
- text: 'Docs',
+ text: 'Guides',
link: '/introduction',
activeMatch: '^/(?!plugins)',
},
+ {
+ text: 'Components',
+ link: '/components/index',
+ activeMatch: '^/components',
+ },
{
text: 'API',
- link: '/api-reference',
+ link: 'https://docs.nativescript.org/api-reference',
activeMatch: '^/api-reference',
target: '_blank',
},
@@ -102,7 +107,7 @@ module.exports = {
sidebar: {
'/best-practices/': getBestPracticeSidebar(),
'/plugins/': getPluginsSidebar(),
-
+ '/components/': getComponentsSidebar(),
// fallback
'/': getSidebar(),
},
@@ -490,6 +495,8 @@ function getSidebar() {
text: 'Basics',
children: [
{ text: 'Introduction', link: '/introduction' },
+ { text: 'Application Architecture', link: '/application-architecture' },
+ { text: 'Project Structure', link: '/project-structure' },
{
text: 'Environment Setup',
link: '/environment-setup',
@@ -509,38 +516,116 @@ function getSidebar() {
],
},
{
- text: 'Running & Building',
+ text: 'Development Workflow',
children: [
{
- text: 'Webpack',
- link: '/webpack',
+ text: 'CLI Basics',
+ link: '/development-workflow/cli-basics',
+ },
+ {
+ text: 'Debugging',
+ link: '/development-workflow/debugging',
+ },
+ {
+ text: 'Running on Virtual Device',
+ link: '/development-workflow/running-on-virtual-device',
+ },
+ {
+ text: 'Running on Physical Device',
+ link: '/development-workflow/running-on-physical-device',
+ },
+ /*{
+ text: 'HMR',
+ link: '/development-workflow/hmr'
+ },*/
+ {
+ text: 'Testing',
+ link: '/development-workflow/testing',
+ },
+ {
+ text: 'Using Packages',
+ link: '/development-workflow/using-packages',
+ },
+ {
+ text: 'Updating',
+ link: '/development-workflow/updating',
+ },
+ {
+ text: 'Choosing an Editor',
+ link: '/development-workflow/choosing-an-editor',
},
],
},
{
- text: 'UI & Styling',
+ text: 'App_Resources',
children: [
{
- text: 'App_Resources',
+ text: 'Understanding App_Resources',
link: '/app-resources',
},
- {
- text: 'UI & Styling',
- link: '/ui-and-styling',
- },
- { text: 'Interaction', link: '/interaction' },
],
},
{
- text: 'Networking',
+ text: '@nativescript/core',
+ children: [
+ { text: 'Application', link: '/nativescript-core/application' },
+ {
+ text: 'ApplicationSettings',
+ link: '/nativescript-core/application-settings',
+ },
+ { text: 'Color', link: '/nativescript-core/color' },
+ { text: 'Connectivity', link: '/nativescript-core/connectivity' },
+ //{ text: 'Virtual Array', link: '/nativescript-core/virtual-array' },
+ { text: 'FileSystem', link: '/nativescript-core/file-system' },
+ { text: 'Fps Meter', link: '/nativescript-core/fps-meter' },
+ { text: 'Http', link: '/nativescript-core/http' },
+ { text: 'ImageSource', link: '/nativescript-core/image-source' },
+ { text: 'Observable', link: '/nativescript-core/observable' },
+ {
+ text: 'Observable Array',
+ link: '/nativescript-core/observable-array',
+ },
+ { text: 'Platform', link: '/nativescript-core/platform' },
+ { text: 'Trace', link: '/nativescript-core/trace' },
+ { text: 'Utils', link: '/nativescript-core/utils' },
+ { text: 'Xml Parser', link: '/nativescript-core/xml-parser' },
+ ],
+ },
+ {
+ text: '@nativescript/webpack',
children: [
- { text: 'Http', link: '/http' },
{
- text: 'Connectivity',
- link: '/connectivity',
+ text: 'Overview',
+ link: 'webpack/overview',
+ },
+ {
+ text: 'Flags & their usage',
+ link: 'webpack/flags-and-their-usage',
+ },
+
+ {
+ text: 'Using .env files',
+ link: 'webpack/using-dot-env-files',
+ },
+ {
+ text: 'Global "magic" variables',
+ link: 'webpack/global-magic-variables',
+ },
+ {
+ text: 'Examples of configurations',
+ link: 'webpack/examples-of-configurations',
+ },
+ {
+ text: 'Plugin API',
+ link: 'webpack/plugin-api',
+ },
+ {
+ text: 'Webpack API',
+ link: 'webpack/api',
},
],
},
+
// {
// text: 'Performance',
// children: [{ text: 'Webpack/Bundle Optimizations', link: '/performance' }],
@@ -559,11 +644,40 @@ function getSidebar() {
],
},
{
- text: 'Advanced Concepts',
+ text: 'Architecture Concepts',
children: [
{
- text: 'Advanced Concepts',
+ text: 'Data Binding',
+ link: '/architecture-concepts/data-binding',
+ },
+ {
+ text: 'Adding Objective C/Swift Code',
+ link: '/architecture-concepts/adding-objectivec-swift-code',
+ },
+ { text: 'Navigation', link: '/architecture-concepts/navigation' },
+ {
+ text: 'Marshalling',
+ link: '/architecture-concepts/marshalling',
+ },
+ {
+ text: 'Metadata',
+ link: '/architecture-concepts/metadata',
+ },
+ {
+ text: 'Memory Management',
+ link: '/architecture-concepts/memory-management',
+ },
+ {
+ text: 'Custom Application and Activity',
+ link: '/architecture-concepts/custom-application-and-activity',
+ },
+ /*{
+ text: 'Layout Process',
link: '/advanced-concepts',
+ },*/
+ {
+ text: 'Property System',
+ link: '/architecture-concepts/property-system',
},
],
},
@@ -651,3 +765,117 @@ function getBestPracticeSidebar() {
},
]
}
+
+function getComponentsSidebar() {
+ return [
+ {
+ text: 'Components',
+ children: [
+ {
+ text: 'Styling',
+ link: '/components/styling',
+ },
+ {
+ text: 'Interaction',
+ link: '/components/interaction',
+ },
+ {
+ text: 'ActionBar',
+ link: '/components/actionbar',
+ },
+ {
+ text: 'ActivityIndicator',
+ link: '/components/activityindicator',
+ },
+ {
+ text: 'Button',
+ link: '/components/button',
+ },
+ {
+ text: 'DatePicker',
+ link: '/components/datepicker',
+ },
+ {
+ text: 'Frame',
+ link: '/components/frame',
+ },
+ {
+ text: 'HtmlView',
+ link: '/components/htmlview',
+ },
+ {
+ text: 'Image',
+ link: '/components/image',
+ },
+ {
+ text: 'Label',
+ link: '/components/label',
+ },
+ {
+ text: 'ListPicker',
+ link: '/components/listpicker',
+ },
+ {
+ text: 'ListView',
+ link: '/components/listview',
+ },
+ {
+ text: 'Page',
+ link: '/components/page',
+ },
+ {
+ text: 'Placeholder',
+ link: '/components/placeholder',
+ },
+ {
+ text: 'Progress',
+ link: '/components/progress',
+ },
+ {
+ text: 'Repeator',
+ link: '/components/repeator',
+ },
+ {
+ text: 'ScrollView',
+ link: '/components/scrollview',
+ },
+ {
+ text: 'SearchBar',
+ link: '/components/searchbar',
+ },
+ {
+ text: 'SegmentedBar',
+ link: '/components/segmentedbar',
+ },
+ {
+ text: 'Slider',
+ link: '/components/slider',
+ },
+ {
+ text: 'Switch',
+ link: '/components/switch',
+ },
+ {
+ text: 'TabView',
+ link: '/components/tabview',
+ },
+ {
+ text: 'TextField',
+ link: '/components/textfield',
+ },
+ {
+ text: 'TextView',
+ link: '/components/textview',
+ },
+ {
+ text: 'TimePicker',
+ link: '/components/timepicker',
+ },
+ {
+ text: 'WebView',
+ link: '/components/webview',
+ },
+ ],
+ },
+ ]
+}
diff --git a/.vitepress/theme/index.js b/.vitepress/theme/index.js
old mode 100644
new mode 100755
diff --git a/.vitepress/theme/nativescript-theme/index.js b/.vitepress/theme/nativescript-theme/index.js
old mode 100644
new mode 100755
index bfbd26b0..f738034e
--- a/.vitepress/theme/nativescript-theme/index.js
+++ b/.vitepress/theme/nativescript-theme/index.js
@@ -689,7 +689,6 @@ function H(e, t, n, r, o, i, a, c, u) {
g && (f.__E = f.__ = null),
(f.__e = !1)
} else t.__e = M(n.__e, t, n, r, o, i, a, u)
-
;(l = s.diffed) && l(t)
} catch (e) {
s.__e(e, t, n)
@@ -8988,7 +8987,6 @@ var script = defineComponent({
})
watch(currentTab, function (next, prev) {
var _tabContainer$value, _tabContainer$value2
-
;(_tabContainer$value = tabContainer.value) === null ||
_tabContainer$value === void 0
? void 0
diff --git a/.vitepress/theme/nativescript-theme/plugins/code-blocks.js b/.vitepress/theme/nativescript-theme/plugins/code-blocks.js
old mode 100644
new mode 100755
diff --git a/.vitepress/theme/nativescript-theme/plugins/device-frame.js b/.vitepress/theme/nativescript-theme/plugins/device-frame.js
old mode 100644
new mode 100755
diff --git a/.vitepress/theme/nativescript-theme/plugins/flavor-container.js b/.vitepress/theme/nativescript-theme/plugins/flavor-container.js
old mode 100644
new mode 100755
diff --git a/.vitepress/theme/nativescript-theme/plugins/index.js b/.vitepress/theme/nativescript-theme/plugins/index.js
old mode 100644
new mode 100755
diff --git a/.vitepress/theme/nativescript-theme/plugins/prism-lang-cli.js b/.vitepress/theme/nativescript-theme/plugins/prism-lang-cli.js
old mode 100644
new mode 100755
diff --git a/.vitepress/theme/nativescript-theme/styles.css b/.vitepress/theme/nativescript-theme/styles.css
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index 591097a6..f87635a1
--- a/README.md
+++ b/README.md
@@ -6,13 +6,13 @@ npm i
npm start
```
-
## Important Note about Plugin Docs
Plugins docs are automatically synced every night via cron job with various plugin workspace repos, for example:
-* https://github.com/NativeScript/firebase
-* https://github.com/NativeScript/plugins
-* https://github.com/NativeScript/payments
+
+- https://github.com/NativeScript/firebase
+- https://github.com/NativeScript/plugins
+- https://github.com/NativeScript/payments
Each plugin workspace can manage it's own README's for documentation and this main central docs will keep itself in sync with them every night.
If you are wanting to modify any plugin documentation, you can do via their plugin workspaces as listed above.
diff --git a/advanced-concepts.md b/advanced-concepts.md
old mode 100644
new mode 100755
diff --git a/app-resources.md b/app-resources.md
old mode 100644
new mode 100755
diff --git a/application-architecture.md b/application-architecture.md
new file mode 100755
index 00000000..f79c5c4c
--- /dev/null
+++ b/application-architecture.md
@@ -0,0 +1,241 @@
+---
+title: Application Architecture
+---
+
+## Application Architecture
+
+In this article we are going to review the architecture of a NativeScript application built with the Core Framework. It will cover the entry point of the app, the decomposition into modules, styling the application and data binding.
+
+### Entry Point
+
+The entry point for a core NativeScript application is declared in the app root folder's package.json file under the property main. This is usually declared as app.js or app.ts in case you have created a TypeScript project. You can use this file to perform app-level initializations, but the primary purpose of the file is to pass control to the app's root module. To do this, you need to call the `Application.run()` method and pass a `NavigationEntry` with the desired `moduleName` as the path to the root module relative to your /app folder.
+
+```js
+import { Application } from '@nativescript/core'
+Application.run({ moduleName: 'app-root' })
+```
+
+```ts
+import { Application } from '@nativescript/core'
+Application.run({ moduleName: 'app-root' })
+```
+
+:::tip Note
+**Important:** Do not place any code after the Application.run() method call as it will not be executed on iOS.
+
+**Important:** Prior to NativeScript 4.0.0 the start() method automatically created an underlying root Frame instance that wrapped your pages. The new run() method will set up the root element of the provided module as the application root element. This effectively means that apart from [Page](/ui/components.md#page) you can now have other roots of your app like [TabView](/ui/components.md#page) and [SideDrawer](/introduction.md#drawer). The start() method is now marked as deprecated.
+:::
+
+### Application Modules
+
+The core NativeScript framework is separated in modules. As a minimum a module is represented by a markup `.xml` file holding the UI markup. From there, you can also add backend `.js`or `.ts` file for executing business logic, a styling `.css` file. The important thing for these additional files is to share the same name with the `.xml` file. For example, the following files make a module:
+
+- `home-page.xml`
+- `home-page.js` or `home-page.ts`
+- `home-page.css`
+
+All functions that are exported by the business logic file are available for binding to the template. The business logic file is a good place to handle events or bind context to the UI, for example below the `loaded` event is bound to a [Page](/ui/components.md#page) component:
+
+```xml
+
+
+
+
+
+
+```
+
+```js
+// home-page.js
+export function onPageLoaded(args) {
+ console.log('Page Loaded')
+}
+```
+
+```ts
+// home-page.ts
+import { EventData } from '@nativescript/core'
+
+export function onPageLoaded(args: EventData): void {
+ console.log('Page Loaded')
+}
+```
+
+
+
+```css
+/* home-page.css */
+.page {
+ background-color: teal;
+}
+```
+
+:::tip Note
+Note that we have put a naming convention in place for modules. Their file names can end in either -root or -page, marking the type of the module. The naming convention isn't mandatory. It is put in place for easier and effortless webpack bundling.
+:::
+
+### Root Modules
+
+These modules are used as the root for UI containers. Currently, there are only two types of UI containers in a NativeScript app:
+
+- The app container - it is only one. You set its root module by passing it to the `Application.run()` method.
+- Modal view containers - You can have a lot of these. You set a modal view's root module by passing it to the `showModal()` method of any UI component.
+
+A root module can have only one component at the root of its content. You can put virtually any UI component as a root, but the most commonly used components are the one that can have children - the [layouts](/ui/components.md#layout-containers), [TabView](/ui/components.md#tabview), SideDrawer or [Frame](/ui/components.md#frame). The `Frame` component can't have children, but it can display and navigate between page modules.
+
+Note that the root module will be loaded regardless of navigations until its UI container disappears. This basically means that the app root module will always be loaded. A modal view root module will be unloaded when the modal view is closed.
+
+Here is an example of an app root module:
+
+```xml
+
+
+```
+
+```js
+// app-root.js
+export function onFrameLoaded(args) {
+ console.log('Frame Loaded')
+}
+```
+
+```ts
+// app-root.ts
+import { EventData } from '@nativescript/core'
+
+export function onFrameLoaded(args: EventData): void {
+ console.log('Frame Loaded')
+}
+```
+
+### Page Modules
+
+These modules represent pages and are used by the Frame component to implement forward and backward navigation. You can pass these modules to the `Frame` in one of the two ways:
+
+- The `defaultPage` attribute - the page module set in this attribute will be initially shown by the Frame.
+- The `navigate()` method - this method forces the `Frame` to hide the currently navigated page module and to show the page module passed as parameter.
+
+Navigation is covered in detail in the [navigation](/architecture-concepts/navigation.md) article.
+
+Page modules must always have the `Page` component at the root of their content. Below is a code sample of a page module:
+
+```xml
+
+
+
+
+
+
+```
+
+```js
+// home-page.js
+export function onPageLoaded(args) {
+ console.log('Page Loaded')
+}
+```
+
+```ts
+// home-page.ts
+import { EventData } from '@nativescript/core'
+
+export function onPageLoaded(args: EventData): void {
+ console.log('Page Loaded')
+}
+```
+
+### Global App Styling
+
+The NativeScript Core framework also provides a way to set application-wide styling. The default place to do that is in the `app.css` file in the app root folder. All css rules that are declared in this file will be applied to all application modules.
+
+You can change the name of the file from which the application-wide CSS is loaded. You need to do the change before the `Application.run()` method is called as shown below:
+
+```js
+import { Application } from '@nativescript/core'
+Application.setCssFileName('style.css')
+
+Application.run({ moduleName: 'main-page' })
+```
+
+Styling is covered in detail in the [styling](/ui/styling.md) article.
+
+### Supporting Multiple Screens
+
+Mobile applications are running on different devices with different screen sizes and form factors. NativeScript provides a way to define different files (`.js`, `.css`, `.xml`, etc.) to be loaded based on the **screen's size**, **platform**, and **orientation** of the current device. The approach is somewhat similar to [multi screen support in Android](http://developer.android.com/guide/practices/screens_support.html). There is a set of _qualifiers_ that can be added inside the file that will be respected when the file is loaded. Here is how the file should look:
+
+_\[.\]\*.\_
+
+In the next section, we will go through the list of supported qualifiers.
+
+### Screen Size Qualifiers
+
+All the values in screen size qualifiers are in `density independent pixels (DP)` — meaning it corresponds to the physical dimensions of the screen. The assumptions are that there are \~160 DP per inch. For example, according to Android guidelines, if the device's smaller dimension is more than 600 dp (~3.75 inches), it is probably a tablet.
+
+- `minWH` - The smaller dimension (width or height) should be at least X dp.#
+- `minW` - Width should be at least `X` dp.
+- `minH` - Height should be at least `X` dp.
+
+Example (separate XML file for tablet and phone):
+
+- `main-page.minWH600.xml` - XML file to be used for tablet devices.
+- `main-page.xml` - XML to be used for phones.
+
+### Platform Qualifiers
+
+- `android` – Android platform
+- `ios` – iOS platform
+
+Example (platform specific files):
+
+- `app.android.css` - CSS styles for Android.
+- `app.ios.css` - CSS styles for iOS.
+ The platform qualifiers are executed **during build time**, while the others are executed **during runtime**.
+ For example, the `app.ios.css` file will not be taken into consideration when building for the Android platform. On the contrary, the **screen size** qualifiers will be considered just after the application runs on a device with specific screen size.
+
+### Orientation Qualifiers
+
+- `land` - orientation is in landscape mode.
+- `port` - orientation is in portrait mode.
+ :::tip Note
+ qualifiers are taken into account when the page is loading. However, changing the device orientation will not trigger a page reload and will not change the current page.
+ :::
+
+### Data Binding
+
+Data binding is the process of connecting application user interface (UI) to a data object (code). In NativeScript each UI component can be bound to what is called a binding source. You can set a binding source to each UI component through its `bindingContext` property. However, this is not the best way to implement binding.
+The `bindingContext` property is inheritable across the visual tree. This means that you can set `bindingContext` to the root component of your module and it will be available to all child components. The binding is then described in the XML using the mustache syntax.
+
+In the following example we set the **bindingContext** of the [Page](/ui/components.md#page) in its `loaded` event handler and then bind the property to the [Label](/ui/components.md#label) text.
+
+```xml
+
+
+
+
+
+
+```
+
+```js
+// home-page.js
+import { fromObject } from '@nativescript/core'
+
+export function onPageLoaded(args) {
+ const page = args.object
+ const source = fromObject({ text: 'Hooray! Home Page loaded!' })
+ page.bindingContext = source
+}
+```
+
+```ts
+// home-page.ts
+import { Page, EventData, fromObject } from '@nativescript/core'
+
+export function onPageLoaded(args: EventData): void {
+ const page: Page = args.object
+ const source = fromObject({ text: 'Hooray! Home Page loaded!' })
+ page.bindingContext = source
+}
+```
+
+Binding is covered in detail in the [data binding](/architecture-concepts/data-binding.md) article.
diff --git a/architecture-concepts/adding-objectivec-swift-code.md b/architecture-concepts/adding-objectivec-swift-code.md
new file mode 100755
index 00000000..9207bd92
--- /dev/null
+++ b/architecture-concepts/adding-objectivec-swift-code.md
@@ -0,0 +1,110 @@
+---
+title: Adding ObjectiveC/Swift Code
+---
+
+## Adding ObjectiveC/Swift Code
+
+For the Objective-C/Swift symbols to be accessible by the Nativescript runtimes the following criteria should be met:
+
+**1)** They need to be compiled and linked
+
+**2)** Metadata needs to be generated for them
+
+The first task is done by the NativeScript CLI by adding the source files to the generated _.xcodeproj_. For the second one the Metadata Generator needs to find a [module.modulemap](https://clang.llvm.org/docs/Modules.html) of the compiled modules.
+
+::: warning Note
+For _.swift_ files _module.modulemap_ is not required.
+:::
+
+In order to satisfy the above constraints the developer has to:
+
+**1)** Place the source files in _App_Resources/iOS/src/_
+
+**2)** Create a modulemap for the Objective-C files
+
+::: warning Note
+Swift classes need to be accessible from the Objective-C runtime in order to be used from NativeScript. This can be done by using the _@objc_ attribute or by inheriting _NSObject_.
+:::
+
+For a detailed walkthrough on how to use native iOS source code in NativeScript [here](https://blog.nativescript.org/adding-objective-c-code-to-a-nativescript-app/).
+
+### Objective C Example
+
+A minimal example for adding native Objective C source code to your NativeScript application:
+
+1. Create ExampleCrypto.m file with the following content:
+
+```objc
+// import required header files
+#import
+#import
+#import "ExampleCrypto.h"
+
+@implementation ExampleCrypto
+
++ (NSString *)generateHMACWithApiKey:(NSString *) apiKey andApiSecret:(NSString *) apiSecret {
+ NSString *hmacData = [NSString stringWithFormat:@"%@%@%@%@%@",apiKey];
+
+ // Make sure the HMAC hash is in hex
+ unsigned char outputHMAC[CC_SHA256_DIGEST_LENGTH];
+ const char* keyChar = [apiSecret cStringUsingEncoding:NSUTF8StringEncoding];
+ const char* dataChar = [hmacData cStringUsingEncoding:NSUTF8StringEncoding];
+ CCHmac(kCCHmacAlgSHA256, keyChar, strlen(keyChar), dataChar, strlen(dataChar), outputHMAC);
+ NSData* hmacHash = [[NSData alloc] initWithBytes:outputHMAC length:sizeof(outputHMAC)];
+
+ NSString* hmacHashHexString = [[hmacHash description] stringByReplacingOccurrencesOfString:@" " withString:@""];
+
+ // Authorization : base64 of hmac hash -->
+ NSString* authorization = [[hmacHashHexString dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
+
+ return authorization;
+}
+
+@end
+```
+
+2. Create ExampleCrypto.h file with the following content:
+
+```objc
+#import
+
+@interface ExampleCrypto : NSObject
+
++ (NSString *)generateHMACWithApiKey:(NSString *)apiKey andApiSecret:(NSString *)apiSecret;
+
+@end
+```
+
+3. Create the module.modulemap file with the following content:
+
+```objc
+module ExampleCrypto {
+ header "ExampleCrypto.h"
+ export *
+}
+```
+
+4. Call the static method from the ObjectiveC source code just added somewhere in your application.
+
+```typescript
+function generateNativeIOSHMAC() {
+ // This if check ensures the following code is only executed on iOS.
+ if (global.isIOS) {
+ const apiKey = '9292skksd88172alekdd782939ssa'
+ const apiSecret = 'f82828282828f992f'
+
+ const base64encryptedKey = ExampleCrypto.generateHMACWithApiKeyandApiSecret(
+ apiKey,
+ apiSecret
+ )
+ console.log('base64encryptedKey', base64encryptedKey)
+ }
+}
+```
+
+5. Build your NativeScript application by running the following and you should see the base64encryptedKey print in your terminal.
+
+```cli
+ns clean
+ns run ios --no-hmr
+```
diff --git a/architecture-concepts/custom-application-and-activity.md b/architecture-concepts/custom-application-and-activity.md
new file mode 100755
index 00000000..a7e13e92
--- /dev/null
+++ b/architecture-concepts/custom-application-and-activity.md
@@ -0,0 +1,303 @@
+---
+title: Custom Application and Activity
+---
+
+## Custom Application and Activity
+
+NativeScript provides a way to create custom `android.app.Application` and `android.app.Activity` implementations.
+
+### Extending the Android Application
+
+1. Create a new TypeScript file in the root of your project folder - name it `application.android.ts` or `application.android.js` if you are using plain JS.
+ ::: tip Note
+ Note the \*.android suffix - we want this file packaged for Android only.
+ :::
+
+2. Copy the following code for TypeScript file:
+
+```ts
+// the `JavaProxy` decorator specifies the package and the name for the native *.JAVA file generated.
+@NativeClass()
+@JavaProxy('org.myApp.Application')
+class Application extends android.app.Application {
+ public onCreate(): void {
+ super.onCreate()
+
+ // At this point modules have already been initialized
+
+ // Enter custom initialization code here
+ }
+
+ public attachBaseContext(baseContext: android.content.Context) {
+ super.attachBaseContext(baseContext)
+
+ // This code enables MultiDex support for the application (if needed)
+ // androidx.multidex.MultiDex.install(this);
+ }
+}
+```
+
+Copy the following code for the JavaScript file:
+
+```js
+const superProto = android.app.Application.prototype
+
+// the first parameter of the `extend` call defines the package and the name for the native *.JAVA file generated.
+android.app.Application.extend('org.myApp.Application', {
+ onCreate: function () {
+ superProto.onCreate.call(this)
+
+ // At this point modules have already been initialized
+
+ // Enter custom initialization code here
+ },
+ attachBaseContext: function (base) {
+ superProto.attachBaseContext.call(this, base)
+ // This code enables MultiDex support for the application (if needed compile androidx.multidex:multidex)
+ // androidx.multidex.MultiDex.install(this);
+ }
+})
+```
+
+3. Modify the application entry within the AndroidManifest.xml file found in the `/App_Resources/Android/` folder:
+
+```xml
+
+```
+
+::: tip Note
+This modification is required by the native platform; it tells Android that your custom Application class will be used as the main entry point of the application.
+:::
+
+4. In order to build the app, the extended Android application should be added to the webpack.config.js file.
+
+```js
+const webpack = require('@nativescript/webpack')
+
+module.exports = env => {
+ webpack.init(env)
+
+ webpack.chainWebpack(config => {
+ if (webpack.Utils.platform.getPlatformName() === 'android') {
+ // make sure the path to the applicatioon.android.(js|ts)
+ // is relative to the webpack.config.js
+ // you may need to use `./app/application.android if
+ // your app source is located inside the ./app folder.
+ config.entry('application').add('./application.android')
+ }
+ })
+
+ return webpack.resolveConfig()
+}
+```
+
+The source code of `application.android.ts` is bundled separately as `application.js` file which is loaded from the native Application.java class on launch.
+
+The `bundle.js` and `vendor.js` files are not loaded early enough in the application launch. That's why the logic in `application.android.ts` is needed to be bundled separately in order to be loaded as early as needed in the application lifecycle.
+
+::: warning Note
+This approach will not work if application.android.ts requires external modules.
+:::
+
+### Extending Android Activity
+
+NativeScript Core ships with a default `androidx.appcompat.app.AppCompatActivity` implementation, that bootstraps the NativeScript application, without forcing users to declare their custom Activity in every project. In some cases you may need to implement a custom Android Activity. In this section we'll look at how to do that!
+
+Create a new `activity.android.ts` or `activity.android.js` when using plain JS.
+
+::: tip Note
+Note the `.android.(js|ts)` suffix - we only want this file on Android.
+:::
+
+A basic Activity looks as follows:
+
+```ts
+import {
+ Frame,
+ Application,
+ setActivityCallbacks,
+ AndroidActivityCallbacks
+} from '@nativescript/core'
+
+@NativeClass()
+@JavaProxy('org.myApp.MainActivity')
+class Activity extends androidx.appcompat.app.AppCompatActivity {
+ public isNativeScriptActivity
+
+ private _callbacks: AndroidActivityCallbacks
+
+ public onCreate(savedInstanceState: android.os.Bundle): void {
+ Application.android.init(this.getApplication())
+ // Set the isNativeScriptActivity in onCreate (as done in the original NativeScript activity code)
+ // The JS constructor might not be called because the activity is created from Android.
+ this.isNativeScriptActivity = true
+ if (!this._callbacks) {
+ setActivityCallbacks(this)
+ }
+
+ this._callbacks.onCreate(this, savedInstanceState, this.getIntent(), super.onCreate)
+ }
+
+ public onNewIntent(intent: android.content.Intent): void {
+ this._callbacks.onNewIntent(this, intent, super.setIntent, super.onNewIntent)
+ }
+
+ public onSaveInstanceState(outState: android.os.Bundle): void {
+ this._callbacks.onSaveInstanceState(this, outState, super.onSaveInstanceState)
+ }
+
+ public onStart(): void {
+ this._callbacks.onStart(this, super.onStart)
+ }
+
+ public onStop(): void {
+ this._callbacks.onStop(this, super.onStop)
+ }
+
+ public onDestroy(): void {
+ this._callbacks.onDestroy(this, super.onDestroy)
+ }
+
+ public onPostResume(): void {
+ this._callbacks.onPostResume(this, super.onPostResume)
+ }
+
+ public onBackPressed(): void {
+ this._callbacks.onBackPressed(this, super.onBackPressed)
+ }
+
+ public onRequestPermissionsResult(
+ requestCode: number,
+ permissions: Array,
+ grantResults: Array
+ ): void {
+ this._callbacks.onRequestPermissionsResult(
+ this,
+ requestCode,
+ permissions,
+ grantResults,
+ undefined /*TODO: Enable if needed*/
+ )
+ }
+
+ public onActivityResult(
+ requestCode: number,
+ resultCode: number,
+ data: android.content.Intent
+ ): void {
+ this._callbacks.onActivityResult(
+ this,
+ requestCode,
+ resultCode,
+ data,
+ super.onActivityResult
+ )
+ }
+}
+```
+
+```js
+import { Frame, Application, setActivityCallbacks } from '@nativescript/core'
+
+const superProto = androidx.appcompat.app.AppCompatActivity.prototype
+androidx.appcompat.app.AppCompatActivity.extend('org.myApp.MainActivity', {
+ onCreate: function (savedInstanceState) {
+ // Used to make sure the App is inited in case onCreate is called before the rest of the framework
+ Application.android.init(this.getApplication())
+
+ // Set the isNativeScriptActivity in onCreate (as done in the original NativeScript activity code)
+ // The JS constructor might not be called because the activity is created from Android.
+ this.isNativeScriptActivity = true
+ if (!this._callbacks) {
+ setActivityCallbacks(this)
+ }
+ // Modules will take care of calling super.onCreate, do not call it here
+ this._callbacks.onCreate(
+ this,
+ savedInstanceState,
+ this.getIntent(),
+ superProto.onCreate
+ )
+
+ // Add custom initialization logic here
+ },
+ onNewIntent: function (intent) {
+ this._callbacks.onNewIntent(
+ this,
+ intent,
+ superProto.setIntent,
+ superProto.onNewIntent
+ )
+ },
+ onSaveInstanceState: function (outState) {
+ this._callbacks.onSaveInstanceState(this, outState, superProto.onSaveInstanceState)
+ },
+ onStart: function () {
+ this._callbacks.onStart(this, superProto.onStart)
+ },
+ onStop: function () {
+ this._callbacks.onStop(this, superProto.onStop)
+ },
+ onDestroy: function () {
+ this._callbacks.onDestroy(this, superProto.onDestroy)
+ },
+ onPostResume: function () {
+ this._callbacks.onPostResume(this, superProto.onPostResume)
+ },
+ onBackPressed: function () {
+ this._callbacks.onBackPressed(this, superProto.onBackPressed)
+ },
+ onRequestPermissionsResult: function (requestCode, permissions, grantResults) {
+ this._callbacks.onRequestPermissionsResult(
+ this,
+ requestCode,
+ permissions,
+ grantResults,
+ undefined
+ )
+ },
+ onActivityResult: function (requestCode, resultCode, data) {
+ this._callbacks.onActivityResult(
+ this,
+ requestCode,
+ resultCode,
+ data,
+ superProto.onActivityResult
+ )
+ }
+ /* Add any other events you need to capture */
+})
+```
+
+:::warning Note
+The `this._callbacks` property is automatically assigned to your extended class by the `frame.setActivityCallbacks` method. It implements the [AndroidActivityCallbacks interface](https://docs.nativescript.org/core-concepts/application-lifecycle#android-activity-events) and allows the core modules to get notified for important Activity events. It is **important** to use these callbacks, as many parts of NativeScript rely on them!
+:::
+
+
+
+Next, modify the activity in `App_Resources/Android/src/main/AndroidManifest.xml`
+
+```xml
+
+```
+
+To include the new Activity in the build, it has to be added to the webpack compilation by editing the `webpack.config.js`:
+
+```js
+const webpack = require('@nativescript/webpack')
+
+module.exports = env => {
+ env.appComponents = (env.appComponents || []).concat(['./src/activity.android'])
+ webpack.init(env)
+
+ return webpack.resolveConfig()
+}
+```
diff --git a/architecture-concepts/data-binding.md b/architecture-concepts/data-binding.md
new file mode 100755
index 00000000..3687fd78
--- /dev/null
+++ b/architecture-concepts/data-binding.md
@@ -0,0 +1,397 @@
+---
+title: Data Binding
+---
+
+## Data Binding
+
+The purpose of this article is to explain what Data Binding is and how it works in NativeScript.
+
+Data binding is the process of connecting application user interface (UI) to a data object (code). It enables changes propagation by reflecting UI modifications in the code and vice versa.
+
+::: tip Note
+
+1. In this article `source` is used as any object in the code and `target` as any UI control (like [TextField](/ui/components.html#textfield)).
+
+2. The article uses StackBlitz IDE + Nativescript Preview app to show different examples of data binding in Nativescript. Use these tools to try out the code snippets provided throughout the article.
+ :::
+
+### Data flow direction
+
+Part of the data binding settings deals with how the data flows between the UI and the data object. NativeScript data binding supports the following data transmissions:
+
+- **One-Way**: This is the default setting, which ensures that the target property updates when a change in the source property occurs. However, UI modification will not update the source property.
+- **Two-Way**: This setting ensures the reflection of changes in both directions — from target to source and source to target. You can use two-way data binding when you need to handle user input.
+
+## Two-way binding
+
+### Binding in code
+
+The example below consists of a Label, TextField and a source property to which the UI controls are bound. First, the **source** object is created with a **textSource** property, initially set to an empty string and then the source object is bound to both the `TextField` and `Label` elements.
+
+Then when the user inputs new string into the `TextField`, the **two-way** binding will update the TextField's text property. Since the Label is bound to the same property, its text property will also be updated. For the Label the data flow is **one-way**,as the changes only propagate from the code to the UI. For a constant flow of changes propagation from the source property to the Label, the source property has to raise a **propertyChange** event in order to notify the Label of the changes. To raise this event, a built-in class is used, which provides this functionality - [Observable](/nativescript-core/observable.md).
+
+
+
+### Binding in XML
+
+To create a binding in XML, a source object is needed, which will be created the same way, as in the example above. Then the binding is created in the XML using a mustache(`{{ }}`) syntax. With an XML declaration, only the names of the properties are set - for the target: text, and for source: textSource. The interesting thing here is that the source of the binding is not specified explicitly.
+
+```xml
+
+
+
+
+
+```
+
+::: tip Note
+When creating UI elements with an XML declaration, the data binding is two-way by default.
+:::
+
+### Binding to a property
+
+An important part of the data binding is setting the source object. For a continuous flow of data changes, the source property needs to emit a **propertyChange** event. NativeScript data binding works with any object that emits this event. Adding a binding source happens by passing it as a second parameter in the method `bind(bindingOptions, source)`. This parameter is optional and could be omitted, in which case a property named **bindingContext** of the `View` class is used as the source. What is special about this property is that it is inheritable across the visual tree. This means that a UI control can use the **bindingContext** of the first of its parent elements, which has an explicitly set **bindingContext**. See [Parent Binding](/architecture-concepts/data-binding.md#parent-binding) In the example from [Binding in Code](/architecture-concepts/data-binding.md#binding-in-code), the **bindingContext** can be set either on a [Page](/ui/components.md#page) instance or a [StackLayout](/ui/components.md#stacklayout) instance and the [TextField](/ui/components.md#textfield) will inherit it as a proper source for the binding of its "text" property.
+
+```js
+page.bindingContext = source
+//or
+stackLayout.bindingContext = source
+```
+
+```ts
+page.bindingContext = source
+//or
+stackLayout.bindingContext = source
+```
+
+### Parent Binding
+
+Another common case in working with bindings is requesting access to the parent binding context. This is because a parent UI element and a child UI element can have different binding contexts and the child UI might need to bind its property to a source property in its parent's **bindingContext**.
+
+Generally, the binding context is inheritable, but not when the elements (items) are created dynamically based on some data source. For example, [ListView](/ui/components.md#listview) creates its child items based on an itemТemplate, which describes what the ListView element will look like. When this element is added to the visual tree, it gets for binding context an element from a ListView items array (with the corresponding index). This process creates a new binding context chain for the child item and its inner UI elements. So, the inner UI element cannot access the binding context of the ListView. In order to solve this problem, NativeScript binding infrastructure has two special keywords: `$parent` and `$parents`. While the first one denotes the binding context of the direct parent visual element, the second one can be used as an array (with a number or string index). This gives you the option to choose either N levels of UI nesting or get a parent UI element with a given type. Let's see how this works with an example.
+
+
+
+::: tip Note
+If the value of the `items` property of the `ListView` is an array of plain elements(numbers,string, dates) as in the preceeding example, you use the `$value` variable to access the current item of the array.
+
+If it is an array of objects,you use the current object property name as the variable name.
+:::
+
+### Binding to an event in XML
+
+There is an option to bind a function to execute on a specific event. This option is available only through an XML declaration. To implement such a functionality, the source object should have an event handler function. The following is an example of binding a function on a button `tap` event.
+
+
+
+```html
+
+
+
+```
+
+```js
+source.set('onTap', function (eventData) {
+ console.log('button is tapped!')
+})
+page.bindingContext = source
+```
+
+```ts
+source.set('onTap', function (eventData) {
+ console.log('button is tapped!')
+})
+page.bindingContext = source
+```
+
+::: tip Note
+Be aware that if there is a button with an event handler function **onTap** within the page code-behind (more info about XML declarations, and **onTap** function within the **bindingContext** object, then there will not be two event handlers hooked up for that button. For executing the function in the code behind, the following syntax should be used in the XML - **tap="onTap"** and for the function from the bindingContext - **tap="{{ onTap }}"**.
+:::
+
+### Using expressions for bindings
+
+You can create a custom expression for bindings. Custom expressions could help in cases when a certain logic should be applied to the UI, while keeping the underlying business data and logic clear. To be more specific, let's see a basic binding expression example. The result should be a TextField element that will display the value of the sourceProperty followed by " some static text" string.
+
+
+
+```html
+
+
+
+
+
+```
+
+:::tip Note
+Binding expression could be used without explicitly named source property. In that case `$value` is used as a source property. However this could lead to problems when a nested property should be observed for changes (e.g. _item.nestedProp_). $value represents bindingContext and when any property of the bindingContext is changed expression will be evaluated. Since nestedProp is not a property of the bindingContext in _item.nestedProp_ then there will be no propertyChange listener attached and changes to _nestedProp_ will not be populated to UI. So it is a good practice to specify which property should be used as source property in order to eliminate such issues.
+:::
+
+The full binding syntax contains three parameters:
+
+1. The first parameter is the source property, which will be listened to for changes.
+2. The second parameter is the expression that will be evaluated.
+3. The third parameter states whether the binding is two-way or not.
+
+As mentioned earlier, XML declaration creates a two-way binding by default, so in the example, the third parameter could be omitted. Keeping the other two properties means that the custom expression will be evaluated only when the sourceProperty changes. The first parameter could also be omitted; if you do that, then the custom expression will not be evaluated every time the bindingContext changes. Thus, the recommended syntax is to include two parameters in the XML declaration, as in our example - the property of interest and the expression, which has to be evaluated.
+
+### Supported Expressions
+
+NativeScript supports different kind of expressions including:
+| Feature| Example| Description|
+|--------|--------|------------|
+|`property access`| `obj1.obj2.prop1`|Resulting in the value of the `prop1` property of the object `obj2`. Expressions in binding are based on polymer expressions, which supports re-evaluation of expression when any value within the dot (`.`) chain is changed. NativeScript uses expressions only in context of bindings (for now), so a binding expression will be re-evaluated only when the binding source property is changed (due to performance considerations). The expression part will not observe and therefore will not initiate re-evaluation.|
+|array access| `arrayVar[indexVar]`| Taking the value of an element in an array (arrayVar) accessed by a valid index for that array (indexVar).|
+|logical operators | `!var1` |Reversing the logical state of the operand - logical not.|
+|unary operators |`+var1`, `-var2`| Converts `var1` into a number. Converts `var2` to a number and negates it.|
+|binary operators | `var1 + var2`| Adding the value of `var2` to `var1`. Supported operators: `+`, `-`, `*`, `/`, `%`.|
+|comparison operators | `var1 > var2` | Comparing whether the value of `var1` is more than the value of `var2`. Other supported operators: `<`, `>`, `<=`, `>=`, `==`, `!=`, `===`, `!==`.|
+|logical comparison operators | `var1>1 && var2>1` | Evaluating whether the value of `var1` is more than 1 `AND` the value of `var2` is more than 2. Supported operators: `&&`, `\|\|`.|
+|ternary operator | `var1 ? var2 : var3` | Evaluating the value of `var1` and if `true`, returns `var2`, else returns `var3`.|
+|grouping parenthesis | (a + b) \* (c + d)|
+|function calls | `myFunc(var1, var2, ..., varN)`| Where `myFunc` is a function available in `bindingContext`(used as context for expression) or within application level resources. The value of the `var1` and `varN` will be used as parameter(s).|
+|filters | `expression \| filter1(param1, ...) \| filter 2` |A filter is an object or a function that is applied to the value of the expression. Within the context of binding, this feature is used as converters. For more information, see the dedicated topic Using Converters in Bindings.|
+:::tip Note
+Special characters need to be escaped as follows:
+
+- " => \"
+- ' => \'
+- < => \<
+- \> => \>
+- & => \&
+ :::
+
+### Using converters in bindings
+
+Speaking of a two-way binding, there is a common problem - having different ways of storing and displaying data. Probably the best example here is the date and time objects. Date and time information is stored as a number or a sequence of numbers (very useful for indexing, searching and other database operations), but this is not the best possible option for displaying date to the application user. Also there is another problem when the user inputs a date (in the example below, the user types into a TextField). The result of the user input will be a string, which will be formatted in accordance with the user's preferences. This string should be converted to a correct date object. Let's see how this could be handled with NativeScript binding.
+The code below shows how to format a TextField input:
+
+
+
+```html
+
+
+
+
+
+```
+
+```js
+import { fromObject } from '@nativescript/core'
+
+export function onNavigatingTo(args) {
+ const dateConverter = {
+ toView(value, format) {
+ let result = format
+ const day = value.getDate()
+ result = result.replace('DD', day < 10 ? `0${day}` : day)
+ const month = value.getMonth() + 1
+ result = result.replace('MM', month < 10 ? `0${month}` : month)
+ result = result.replace('YYYY', value.getFullYear())
+
+ return result
+ },
+ toModel(value, format) {
+ const ddIndex = format.indexOf('DD')
+ const day = parseInt(value.substr(ddIndex, 2), 10)
+ const mmIndex = format.indexOf('MM')
+ const month = parseInt(value.substr(mmIndex, 2), 10)
+ const yyyyIndex = format.indexOf('YYYY')
+ const year = parseInt(value.substr(yyyyIndex, 4), 10)
+ const result = new Date(year, month - 1, day)
+
+ return result
+ }
+ }
+
+ const page = args.object
+ const viewModel = fromObject({
+ dateConverter,
+ testDate: new Date()
+ })
+
+ page.bindingContext = viewModel
+}
+```
+
+```ts
+import { Page, EventData, fromObject } from '@nativescript/core'
+
+export function onNavigatingTo(args: EventData) {
+ const dateConverter = {
+ toView(value, format) {
+ let result = format
+ const day = value.getDate()
+ result = result.replace('DD', day < 10 ? '0' + day : day)
+ const month = value.getMonth() + 1
+ result = result.replace('MM', month < 10 ? '0' + month : month)
+ result = result.replace('YYYY', value.getFullYear())
+
+ return result
+ },
+ toModel(value, format) {
+ const ddIndex = format.indexOf('DD')
+ const day = parseInt(value.substr(ddIndex, 2), 10)
+ const mmIndex = format.indexOf('MM')
+ const month = parseInt(value.substr(mmIndex, 2), 10)
+ const yyyyIndex = format.indexOf('YYYY')
+ const year = parseInt(value.substr(yyyyIndex, 4), 10)
+ const result = new Date(year, month - 1, day)
+
+ return result
+ }
+ }
+
+ const page = args.object
+ const viewModel = fromObject({
+ dateConverter,
+ testDate: new Date()
+ })
+
+ page.bindingContext = viewModel
+}
+```
+
+Note the special operator `\|` within the expression. The above code snippet (both XML and JavaScript) will display a date in a `DD.MM.YYYY` format (`toView()` function), and when a new date is entered with the same format, it is converted to a valid Date object (`toModel()` function). A Converter object should have one or two functions (`toView()` and `toModel()`) executed every time when a data should be converted. The `toView()` function is called when data will be displayed to the end user as a value of any UI view, and the `toModel()` function will be called when there is an editable element (like TextField) and the user enters a new value. In the case of one-way binding, the Converter object could have only a `toView()` function or it should be a function. All converter functions have an array of parameters where the first parameter is the value that will be converted, and all other parameters are custom parameters defined in the converter definition.
+
+:::tip Note
+Any run-time error within the converter methods (`toView()` and `toModel()`) will be handled automatically and the application will not break, but the data in the view-model will not be altered (in case of error) and an error message with more information will be logged to the console. To enable it, use the built-in [Trace](/nativescript-core/trace.md) with an `Trace.categories.Error` category. A date converter is simplified just for the sake of the example and it is not supposed to be used as a fully functional converter from date to string and vice versa. The best way to get a date from a user is to use a [DatePicker](/ui/components.md#date-picker).
+:::
+
+A converter can accept not only static custom parameters, but any value from the bindingContext. For example:
+
+
+
+```html
+
+
+
+
+
+```
+
+```ts
+import { Page, EventData, fromObject } from '@nativescript/core'
+
+export function onNavigatingTo(args: EventData) {
+ const dateConverter = {
+ toView(value, format) {
+ let result = format
+ const day = value.getDate()
+ result = result.replace('DD', day < 10 ? '0' + day : day)
+ const month = value.getMonth() + 1
+ result = result.replace('MM', month < 10 ? '0' + month : month)
+ result = result.replace('YYYY', value.getFullYear())
+
+ return result
+ },
+ toModel(value, format) {
+ const ddIndex = format.indexOf('DD')
+ const day = parseInt(value.substr(ddIndex, 2), 10)
+ const mmIndex = format.indexOf('MM')
+ const month = parseInt(value.substr(mmIndex, 2), 10)
+ const yyyyIndex = format.indexOf('YYYY')
+ const year = parseInt(value.substr(yyyyIndex, 4), 10)
+ const result = new Date(year, month - 1, day)
+
+ return result
+ }
+ }
+
+ const page = args.object
+ const viewModel = fromObject({
+ dateConverter,
+ dateFormat: 'DD.MM.YYYY',
+ testDate: new Date()
+ })
+
+ page.bindingContext = viewModel
+}
+```
+
+Setting a converter function and a parameter within the bindingContext is very useful for ensuring proper conversion of data. However, this is not the case when [ListView](/ui/components.md#listview) items should be bound. The problem comes from the fact that the bindingContext of a ListView is the individual data items in the array, and to apply a converter, the converter and its parameters should be added to the each data item, which will result in multiple converter instances. Tackling this problem with NativeScript is fairly simple. the binding infrastructure search in the application level resources to find a proper converter and parameters. So you could add the converters to the resources in the [Application](/nativescript-core/application.md) class. To be more clear, examine the following example (both XML and JavaScript):
+
+
+
+```html
+
+
+
+
+
+
+
+
+
+```
+
+```js
+import { Application, Page, EventData, fromObject } from '@nativescript/core'
+
+export function onNavigatingTo(args) {
+ const list = []
+ for (let i = 0; i < 5; i++) {
+ list.push({ itemDate: new Date() })
+ }
+
+ const dateConverter = (value, format) => {
+ let result = format
+ const day = value.getDate()
+ result = result.replace('DD', day < 10 ? `0${day}` : day)
+ const month = value.getMonth() + 1
+ result = result.replace('MM', month < 10 ? `0${month}` : month)
+ result = result.replace('YYYY', value.getFullYear())
+
+ return result
+ }
+
+ Application.getResources().dateConverter = dateConverter
+ Application.getResources().dateFormat = 'DD.MM.YYYY'
+
+ const page = args.object
+ const viewModel = fromObject({
+ items: list
+ })
+
+ page.bindingContext = viewModel
+}
+```
+
+```ts
+import { Application, Page, EventData, fromObject } from '@nativescript/core'
+
+export function onNavigatingTo(args: EventData) {
+ const list = []
+ for (let i = 0; i < 5; i++) {
+ list.push({ itemDate: new Date() })
+ }
+
+ const dateConverter = (value, format) => {
+ let result = format
+ const day = value.getDate()
+ result = result.replace('DD', day < 10 ? '0' + day : day)
+ const month = value.getMonth() + 1
+ result = result.replace('MM', month < 10 ? '0' + month : month)
+ result = result.replace('YYYY', value.getFullYear())
+
+ return result
+ }
+
+ application.getResources().dateConverter = dateConverter
+ application.getResources().dateFormat = 'DD.MM.YYYY'
+
+ const page = args.object
+ const viewModel = fromObject({
+ items: list
+ })
+
+ page.bindingContext = viewModel
+}
+```
+
+### Stop binding
+
+Generally there is no need to stop binding explicitly since a Binding object uses weak references, which prevents any memory leaks. However, there are some scenarios where binding must be stopped. In order to stop an existing data binding, just call the **unbind()** method with the target property name as the argument.
+
+```ts
+targetTextField.unbind('text')
+```
diff --git a/architecture-concepts/marshalling.md b/architecture-concepts/marshalling.md
new file mode 100755
index 00000000..a98cfca0
--- /dev/null
+++ b/architecture-concepts/marshalling.md
@@ -0,0 +1,1167 @@
+---
+title: Marshalling
+---
+
+# Marshalling
+
+### iOS Marshalling
+
+NativeScript for iOS handles the conversion between JavaScript and Objective-C data types implicitly. However, the rules that govern this conversion need to take into account the differences between JavaScript and Objective-C. NativeScript tries to translate idioms between languages, but there are quirks and features in both that are hard to reconcile. The following is a thorough but not exhaustive list of rules and exceptions NativeScript abides by when exposing Objective-C APIs in JavaScript.
+
+#### Objective-C Classes and Objects
+
+The most common data type in Objective-C by far is the class. Classes can have instance or static methods, and properties which are always instance. NativeScript exposes an Objective-C class and its members as a JavaScript constructor function with an associated prototype according to the [prototypal inheritance model](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain). This means that each static method on an Objective-C class becomes a function on its JavaScript constructor function, each instance method becomes a function on the JavaScript prototype, and each property becomes a property descriptor on the same prototype. Every JavaScript constructor function created to expose an Objective-C class is arranged in a prototype chain that mirrors the class hierarchy in Objective-C: if `NSMutableArray` extends `NSArray`, which in turn extends `NSObject` in Objective-C, then in JavaScript the prototype of the `NSObject` constructor function is the prototype of `NSArray`, which in turn is the prototype of `NSMutableArray`.
+
+To illustrate:
+
+```objc
+@interface NSArray : NSObject
+
++ (instancetype)arrayWithArray:(NSArray *)anArray;
+
+- (id)objectAtIndex:(NSUInteger)index;
+
+@property (readonly) NSUInteger count;
+
+@end
+```
+
+```js
+var NSArray = {
+ __proto__: NSObject,
+
+ arrayWithArray: function () {
+ [native code]
+ }
+}
+
+NSArray.prototype = {
+ __proto__: NSObject.prototype,
+
+ constructor: NSArray,
+
+ objectAtIndex: function () {
+ [native code]
+ },
+
+ get count() {
+ [native code]
+ }
+}
+```
+
+Instances of Objective-C classes exist in JavaScript as special "wrapper" exotic objects - they keep track of and reference native objects, as well as manage their memory. When a native API returns an Objective-C object, NativeScript constructs such a wrapper for it in case one doesn't already exist. Wrappers have a prototype just like regular JavaScript objects. This prototype is the same as the prototype of the JavaScript constructor function that exposes the class the native object is an instance of. In essence:
+
+```js
+const tableViewController = new UITableViewController() // returns a wrapper around a UITableViewController instance
+Object.getPrototypeOf(tableViewController) === UITableViewController.prototype // returns true
+```
+
+There is only one JavaScript wrapper around an Objective-C object, always. This means that Objective-C wrappers maintain JavaScript identity equality:
+
+```js
+tableViewController.tableView === tableViewController.tableView
+```
+
+Calling native APIs that expect Objective-C classes or objects is easy - just pass the JavaScript constructor function for the class, or the wrapper for the object.
+
+If an API is declared as accepting a `Class` in Objective-C, the argument in JavaScript is the constructor function:
+
+```objc
+NSString *className = NSStringFromClass([NSArray class]);
+```
+
+```js
+const className = NSStringFromClass(NSArray)
+```
+
+Conversely, if an API is declared as accepting an instance of a specific class such as `NSDate`, the argument is a wrapper around an object inheriting from that class.
+
+```objc
+NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
+NSDate *date = [NSDate date];
+NSString *formattedDate = [formatter stringFromDate:date];
+```
+
+```js
+const formatter = new NSDateFormatter()
+const date = NSDate.date()
+const formattedDate = formatter.stringFromDate(date)
+```
+
+An API expecting the `id` data type in Objective-C means it will any accept Objective-C class or object in JavaScript.
+
+```objc
+NSMutableArray *array = [[NSMutableArray alloc] init];
+Class buttonClass = [UIButton class];
+UIButton *button = [[buttonClass alloc] init];
+[array setObject:buttonClass atIndex:0];
+[array setObject:button atIndex:1];
+```
+
+```js
+const array = new NSMutableArray()
+const buttonClass = UIButton
+const button = new buttonClass()
+array.setObjectAtIndex(buttonClass, 0)
+array.setObjectAtIndex(button, 1)
+```
+
+#### Converting JavaScript array to CGFloat array
+
+In the below-given code sample, you can see, how to convert a JavaScript array to a `CGFloat` array.
+In the tabs, you will find the Objective-C code for a function accepting a `CGFloat` array as an argument and the JavaScript code for calling this native function.
+
+```js
+const CGFloatArray = interop.sizeof(interop.types.id) == 4 ? Float32Array : Float64Array
+const jsArray = [4.5, 0, 1e-5, -1242e10, -4.5, 34, -34, -1e-6]
+
+FloatArraySample.dumpFloats(CGFloatArray.from(jsArray), jsArray.length)
+```
+
+```objc
+@interface FloatArraySample
++ (void)dumpFloats:(CGFloat*) arr withCount:(int)cnt;
+@end
+
+@implementation TNSBaseInterface
+
++ (void)dumpFloats:(CGFloat*) arr withCount:(int)cnt {
+ for(int i = 0; i < cnt; i++) {
+ NSLog(@"arr[%d] = %f", i, arr[i]);
+ }
+}
+@end
+```
+
+::: warning Note
+Keep in mind that `CGFloat` is architecture dependent. On 32-bit devices, we need to use `Float32Array` and `Float64Array` -- on 64-bit ones. A straightforward way to verify the device/emulator architecture is to check the pointer size via `interop.sizeof(interop.types.id)`. The return value for the pointer size will be 4 bytes for 32-bit architectures and 8 bytes - for 64-bit ones. For further info, check out [CGFloat's documentation](https://developer.apple.com/documentation/coregraphics/cgfloat).
+:::
+
+#### Primitive Exceptions
+
+NativeScript considers instances of `NSNull`, `NSNumber`, `NSString` and `NSDate` to be "primitives". This means that instances of these classes won't be exposed in JavaScript via a wrapper exotic object, instead they will be converted to the equivalent JavaScript data type: `NSNull` becomes `null`, `NSNumber` becomes `number` or `boolean`, `NSString` becomes `string` and `NSDate` becomes `Date`. The exception to this are the methods on those classes declared as returning `instancetype` - init methods and factory methods. This means that a call to `NSString.stringWithString` whose return type in Objective-C is `instancetype` will return a wrapper around an `NSString` instance, rather than a JavaScript string. This applies for all methods on `NSNull`, `NSNumber`, `NSString` and `NSDate` returning `instancetype`.
+
+On the other hand, any API that expects a `NSNull`, `NSNumber`, `NSString` or `NSDate` instance in Objective-C can be called either with a wrapper object or a JavaScript value - `null`, `number` or `boolean`, `string` or `Date`, in JavaScript. The conversion is automatically handled by NativeScript.
+
+More information on how NativeScript deals with Objective-C classes is available [here](/advanced-concepts.html#objective-c-classes-and-objects).
+
+#### Objective-C Protocols
+
+Protocols in Objective-C are like interfaces in other languages - they are blueprints of what members a class should contain, a sort of an API contract. Protocols are exposed as empty objects in JavaScript. Protocols are usually only referenced when [subclassing](#ObjC-Subclassing) an Objective-C class or when checking whether an object or class conforms to a protocol.
+
+
+
+```objc
+BOOL isCopying = [NSArray conformsToProtocol:@protocol(NSCopying)];
+```
+
+```js
+const isCopying = NSArray.conformsToProtocol(NSCopying)
+```
+
+#### Objective-C Selectors
+
+In Objective-C `SEL` is a data type that represents the name of a method of an Objective-C class. NativeScript exposes this data type as a JavaScript string. Whenever an API expects a selector value in Objective-C, it's JavaScript projection will expect a string with the method name.
+
+```objc
+NSMutableString *aString = [[NSMutableString alloc] init];
+BOOL hasAppend = [aString respondsToSelector:@selector(appendString:)];
+```
+
+```js
+const aString = NSMutableString.alloc().init()
+const hasAppend = aString.respondsToSelector('appendString:')
+```
+
+#### Objective-C Blocks
+
+[Objective-C blocks](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html) are anonymous functions in Objective-C. They can be closures, just like JavaScript functions, and are often used as callbacks. NativeScript implicitly exposes an Objective-C block as a JavaScript function. Any API that accepts a block in Objective-C accepts a JavaScript function when called in JavaScript:
+
+```objc
+NSURL *url = [NSURL URLWithString:@"http://example.com"];
+NSURLRequest *request = [NSURLRequest requestWithURL:url];
+[NSURLConnection sendAsynchronousRequest:request queue:nil completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
+ NSLog(@"request complete");
+}];
+```
+
+```js
+const url = NSURL.URLWithString('http://example.com')
+const request = NSURLRequest.requestWithURL(url)
+NSURLConnection.sendAsynchronousRequestQueueCompletionHandler(
+ request,
+ null,
+ (response, data, connectionError) => {
+ console.log('request complete')
+ }
+)
+```
+
+Blocks in Objective-C, especially blocks that are closures, need to be properly retained and released in order to not leak memory. NativeScript does this automatically - a block exposed as a JavaScript function is released as soon as the function is garbage collected. A JavaScript function implicitly converted to a block will not be garbage collected as long the block is not released.
+
+#### CoreFoundation Objects
+
+iOS contains both an Objective-C standard library (the Foundation framework) and a pure C standard library (Core Foundation). Core Foundation is modeled after Foundation to a great extent and implements a limited object model. Data types such as CFDictionaryRef and CFBundleRef are Core Foundation objects. Core Foundation objects are retained and released just like Objective-C objects, using the CFRetain and CFRelease functions. NativeScript implements automatic memory management for functions that are annotated as returning a retained Core Foundation object. For those that are not annotated, NativeScript returns an Unmanaged type that wraps the Core Foundation instance. This makes you partially responsible for keeping the instance allive. You could either
+
+- Call takeRetainedValue() which would return managed reference to the wrapped instance, decrementing the reference count while doing so
+- Call takeUnretainedValue() which would return managed reference to the wrapped instance _without_ decrementing the reference count
+
+#### Toll-free Bridging
+
+Core Foundation has the concept of [Toll-free bridged types](https://developer.apple.com/library/ios/documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/tollFreeBridgedTypes.html) - data types which can be used interchangeably with their Objective-C counterparts. When dealing with a toll-free bridged type NativeScript always treats it as its Objective-C counterpart. Core Foundation objects on the [toll-free bridged types list](https://developer.apple.com/library/ios/documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/tollFreeBridgedTypes.html#//apple_ref/doc/uid/TP40010677-SW4) are exposed as if they were instances of the equivalent Objective-C class. This means that a `CFDictionaryRef` value in JavaScript has the same methods on its prototype as if it were a `NSDictionary` object. Unlike regular Core Foundation objects, toll-free bridged types are automatically memory managed by NativeScript, so there is no need to retain or release them using `CFRetain` and `CFRelease`.
+
+#### Null Values
+
+Objective-C has three null values - `NULL`, `Nil` and `nil`. `NULL` means a regular C pointer to zero, `Nil` is a `NULL` pointer to an Objective-C class, and `nil` is a `NULL` pointer to an Objective-C object. They are implicitly converted to `null` in JavaScript. When calling a native API with a `null` argument NativeScript converts the JavaScript null value to a C pointer to zero. Some APIs require their arguments to not be pointers to zero - invoking them with null in JavaScript can potentially crash the application without a chance to recover.
+
+#### Numeric Types
+
+Integer and floating point data types in Objective-C are converted to JavaScript numbers. This includes types such as `char`, `int`, `long`, `float`, `double`, `NSInteger` and their unsigned variants. However, integer values larger than ±253 will lose their precision because the JavaScript number type is limited in size to 53-bit integers.
+
+#### Struct Types
+
+NativeScript exposes Objective-C structures as JavaScript objects. The properties on such an object are the same as the fields on the structure it exposes. APIs that expect a struct type in Objective-C can be called with a JavaScript object with the same shape as the structure:
+
+```objc
+CGRect rect = {
+ .origin = {
+ .x = 0,
+ .y = 0
+ },
+ .size = {
+ .width = 100,
+ .height = 100
+ }
+};
+UIView *view = [[UIView alloc] initWithFrame:rect];
+```
+
+```js
+const rect = {
+ origin: {
+ x: 0,
+ y: 0
+ },
+ size: {
+ width: 100,
+ height: 100
+ }
+}
+const view = UIView.alloc().initWithFrame(rect)
+```
+
+More information on how NativeScript deals with structures is available [here](#C-Structures).
+
+
+
+#### `NSError **` marshalling
+
+#### Native to JavaScript
+
+```objc
+@interface NSFileManager : NSObject
++ (NSFileManager *)defaultManager;
+- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error;
+@end
+```
+
+We can use this method from JavaScript in the following way:
+
+```js
+const fileManager = NSFileManager.defaultManager
+const bundlePath = NSBundle.mainBundle.bundlePath
+
+console.log(fileManager.contentsOfDirectoryAtPathError(bundlePath, null))
+```
+
+If we want to check the error using out parameters:
+
+```js
+const errorRef = new interop.Reference()
+fileManager.contentsOfDirectoryAtPathError('/not-existing-path', errorRef)
+console.log(errorRef.value) // NSError: "The folder '/not-existing-path' doesn't exist."
+```
+
+Or we can skip passing the **last NSError \*\*** out parameter and a JavaScript error will be thrown if the `NSError **` is set from native:
+
+```js
+try {
+ fileManager.contentsOfDirectoryAtPathError('/not-existing-path')
+} catch (e) {
+ console.log(e) // NSError: "The folder '/not-existing-path' doesn't exist."
+}
+```
+
+#### JavaScript to Native
+
+When overriding a method having **NSError ** out parameter in the end** any thrown JavaScript error will be wrapped and set to the `NSError **` argument (if given).
+
+#### Pointer Types
+
+Languages in the C family have the notion of a pointer data type. A pointer is a value that points to another value, or, more accurately, to the location of that value in memory. JavaScript has no notion of pointers, but the pointer data type is used throughout the iOS SDK. To overcome this, NativeScript introduces the `Reference` object. References are special objects which allow JavaScript to reason about and access pointer values. Consider this example:
+
+```objc
+NSFileManager *fileManager = [NSFileManager defaultManager];
+BOOL isDirectory;
+BOOL exists = [fileManager fileExistsAtPath:@"/var/log" isDirectory:&isDirectory];
+if (isDirectory) {
+ NSLog(@"The path is actually a directory");
+}
+```
+
+This snippet calls the `fileExistsAtPath:isDirectory` method of the `NSFileManager` class. This method accepts a `NSString` as its first argument and a pointer to a boolean value as its second argument. During its execution the method will use the pointer to update the boolean value. This means it will directly change the value of `isDirectory`. The same code can be written as follows:
+
+```js
+const fileManager = NSFileManager.defaultManager
+const isDirectory = new interop.Reference()
+const exists = fileManager.fileExistsAtPathIsDirectory('/var/log', isDirectory)
+if (isDirectory.value) {
+ console.log('The path is actually a directory')
+}
+```
+
+### Android Marshalling
+
+#### Data Conversion
+
+Being two different worlds, Java/Kotlin and JavaScript use different data types. For example java.lang.String is not the same as the JavaScript's String. The NativeScript Runtime provides implicit type conversion that projects types and values from JavaScript to Java and vice-versa. The Kotlin support in the runtime is similar and data conversion is described in the articles JavaScript to Kotlin and Kotlin to JavaScript There are several corner cases - namely with different method overloads, where an explicit input is required to call the desired method but these cases are not common and a typical application will seldom (if ever) need such explicit conversion.
+
+#### JavaScript to Java Conversion
+
+The article lists the available types in JavaScript and how they are projected to Java.
+
+##### String
+
+JavaScript [String](http://www.w3schools.com/jsref/jsref_obj_string.asp) maps to [java.lang.String](http://developer.android.com/reference/java/lang/String.html):
+
+```js
+var context = ...;
+var button = new android.widget.Button(context);
+var text = "My Button"; // JavaScript string
+button.setText(text); // text is converted to java.lang.String
+```
+
+##### Boolean
+
+JavaScript [Boolean](http://www.w3schools.com/js/js_booleans.asp) maps to Java primitive [boolean](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html).
+
+```js
+var context = ...;
+var button = new android.widget.Button(context);
+var enabled = false; // JavaScript Boolean
+button.setEnabled(enabled); // enabled is converted to Java primitive boolean
+```
+
+##### Undefined & Null
+
+JavaScript [Undefined](http://www.w3schools.com/jsref/jsref_undefined.asp) & [Null](https://www.w3schools.com/js/js_type_conversion.asp) maps to Java [null literal](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.7) (or null pointer).
+
+```js
+var context = ...;
+var button = new android.widget.Button(context);
+button.setOnClickListener(undefined); // the Java call will be made using the null keyword
+```
+
+##### Number
+
+Java has several primitive numeric types while JavaScript has the [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp) type only. Additionally, unlike JavaScript, Java is a language that supports [Method Overloading](http://en.wikipedia.org/wiki/Function_overloading), which makes the numeric conversion more complex. Consider the following Java class:
+
+```java
+class MyObject extends java.lang.Object {
+ public void myMethod(byte value){
+ }
+
+ public void myMethod(short value){
+ }
+
+ public void myMethod(int value){
+ }
+
+ public void myMethod(long value){
+ }
+
+ public void myMethod(float value){
+ }
+
+ public void myMethod(double value){
+ }
+}
+```
+
+The following logic applies when calling `myMethod` on a `myObject` instance from JavaScript:
+
+```js
+var myObject = new MyObject()
+```
+
+- Implicit **integer** conversion:
+
+```js
+myObject.myMethod(10) // myMethod(int) will be called.
+```
+
+::: warning Note
+If there is no myMethod(int) implementation, the Runtime will try to choose the best possible overload with least conversion loss. If no such method is found an exception will be raised.
+:::
+
+- Implicit **floating-point** conversion:
+
+```js
+myObject.myMethod(10.5) // myMethod(double) will be called.
+```
+
+::: warning Note
+If there is no myMethod(double) implementation, the Runtime will try to choose the best possible overload with least conversion loss. If no such method is found an exception will be raised.
+:::
+
+- Explicitly call an overload:
+ To enable developers call a specific method overload, the Runtime exposes the following functions directly in the global context:
+
+ * byte(number) → Java primitive byte
+
+ > The number value will be truncated and only its first byte of the whole part will be used.
+
+ * short(number) → Java primitive short
+
+ > The number value will be truncated and only its first 2 bytes of the whole part will be used.
+
+ * float(number) → Java primitive float
+
+ > The number value will be converted (with a possible precision loss) to a 2^32 floating-point value.
+
+ * long(number) → Java primitive long (in case the number literal fits JavaScript 2^53 limit)
+
+ > The number value's whole part will be taken only.
+
+ * long("number") → Java primitive long (in case the number literal doesn't fit JavaScript 2^53 limit)
+
+```js
+myObject.myMethod(byte(10)) // will call myMethod(byte)
+myObject.myMethod(short(10)) // will call myMethod(short)
+myObject.myMethod(float(10)) // will call myMethod(float)
+myObject.myMethod(long(10)) // will call myMethod(long)
+myObject.myMethod(long('123456')) // will convert "123456" to Java long and will call myMethod(long)
+```
+
+::: warning Note
+When an explicit cast function is called and there is no such implementation found, the Runtime will directly fail, without trying to find a matching overload.
+:::
+
+##### Array
+
+A JavaScript [Array](http://www.w3schools.com/jsref/jsref_obj_array.asp) is implicitly converted to a [Java Array](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html), using the above described rules for type conversion of the array's elements. For example:
+
+```java
+class MyObject extends java.lang.Object {
+ public void myMethod(java.lang.String[] items){
+ }
+}
+```
+
+```js
+var items = ['One', 'Two', 'Three']
+var myObject = new MyObject()
+myObject.myMethod(items) // will convert to Java array of java.lang.String objects
+```
+
+#### Javascript to Kotlin Conversion
+
+The article lists the available types in JavaScript and how they are projected to Kotlin.
+
+##### String
+
+JavaScript [String](http://www.w3schools.com/jsref/jsref_obj_string.asp) maps to [kotlin.String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithStringProperty()
+var text = 'My Button' // JavaScript string
+kotlinClass.setStringProperty(text) // text is converted to kotlin.String
+```
+
+##### Boolean
+
+JavaScript [Boolean](http://www.w3schools.com/js/js_booleans.asp) maps to Kotlin class [Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html).
+
+```js
+var kotlinClass = new com.example.KotlinClassWithBooleanProperty()
+var enabled = false // JavaScript Boolean
+kotlinClass.setBooleanProperty(enabled) // enabled is converted to Kotlin Boolean
+```
+
+##### Undefined & Null
+
+JavaScript [Undefined](http://www.w3schools.com/jsref/jsref_undefined.asp) & [Null](https://www.w3schools.com/js/js_type_conversion.asp) maps to Kotlin null literal (or null pointer).
+
+```js
+var kotlinClass = new com.example.KotlinClassWithNullableParameter(undefined) // the Kotlin call will be made using the null keyword
+```
+
+##### Number
+
+Kotlin has several numeric types while JavaScript has the [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp) type only. Additionally, unlike JavaScript, Kotlin is a language that supports [Method Overloading](http://en.wikipedia.org/wiki/Function_overloading), which makes the numeric conversion more complex. Consider the following Java class:
+
+```kotlin
+class MyObject : Any() {
+ fun myMethod(value: Byte) {}
+
+ fun myMethod(value: Short) {}
+
+ fun myMethod(value: Int) {}
+
+ fun myMethod(value: Long) {}
+
+ fun myMethod(value: Float) {}
+
+ fun myMethod(value: Double) {}
+}
+```
+
+The following logic applies when calling `myMethod` on a `myObject` instance from JavaScript:
+
+```js
+var myObject = new MyObject()
+```
+
+- Implicit **integer** conversion:
+
+```js
+myObject.myMethod(10) // myMethod(Int) will be called.
+```
+
+::: warning Note
+If there is no myMethod(Int) implementation, the Runtime will try to choose the best possible overload with least conversion loss. If no such method is found an exception will be raised.
+:::
+
+- Implicit **floating-point** conversion:
+
+```js
+myObject.myMethod(10.5) // myMethod(Double) will be called.
+```
+
+::: warning Note
+If there is no myMethod(Double) implementation, the Runtime will try to choose the best possible overload with least conversion loss. If no such method is found an exception will be raised.
+:::
+
+- Explicitly call an overload:
+ To enable developers call a specific method overload, the Runtime exposes the following functions directly in the global context:
+
+ * byte(number) → Kotlin Byte
+
+ >The number value will be truncated and only its first byte of the whole part will be used.
+
+ * short(number) → Kotlin Short
+
+ >The number value will be truncated and only its first 2 bytes of the whole part will be used.
+
+ * float(number) → Kotlin Float
+
+ >The number value will be converted (with a possible precision loss) to a 2^32 floating-point value.
+
+ * long(number) → Kotlin Long (in case the number literal fits JavaScript 2^53 limit)
+
+ >The number value's whole part will be taken only.
+
+ * long("number") → Kotlin Long (in case the number literal doesn't fit JavaScript 2^53 limit)
+
+```js
+myObject.myMethod(byte(10)) // will call myMethod(Byte)
+myObject.myMethod(short(10)) // will call myMethod(Short)
+myObject.myMethod(float(10)) // will call myMethod(Float)
+myObject.myMethod(long(10)) // will call myMethod(Long)
+myObject.myMethod(long('123456')) // will convert "123456" to Kotlin Long and will call myMethod(Long)
+```
+
+::: warning Note
+When an explicit cast function is called and there is no such implementation found, the Runtime will directly fail, without trying to find a matching overload.
+:::
+
+##### Array
+
+A JavaScript [Array](http://www.w3schools.com/jsref/jsref_obj_array.asp) is implicitly converted to a [Kotlin Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html), using the above described rules for type conversion of the array's elements. For example:
+
+```kotlin
+class MyObject : Any() {
+ fun myMethod(items: Array) {}
+}
+```
+
+```js
+var items = ['One', 'Two', 'Three']
+var myObject = new MyObject()
+myObject.myMethod(items) // will convert to Java array of java.lang.String objects
+```
+
+#### Java to Javascript Conversion
+
+The article lists the available types in Java and how they are projected to JavaScript.
+
+##### String & Character
+
+Both [java.lang.String](http://developer.android.com/reference/java/lang/String.html) and [java.lang.Character](http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html) types are projected as JavaScript [String](http://www.w3schools.com/jsref/jsref_obj_string.asp):
+
+```js
+var file = new java.io.File('/path/to/file')
+var path = file.getPath() // returns java.lang.String, converted to JS String
+```
+
+##### Boolean & Primitive boolean
+
+Both the primitive [boolean](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) and reference [java.lang.Boolean](http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html) types are projected as JavaScript [Boolean](http://www.w3schools.com/jsref/jsref_obj_boolean.asp):
+
+```js
+var context = ...
+var button = new android.widget.Button(context);
+var enabled = button.isEnabled(); // returns primitive boolean, converted to JS Boolean
+```
+
+##### Byte & Primitive byte
+
+Both the primitive [byte](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) and reference [java.lang.Byte](http://docs.oracle.com/javase/7/docs/api/java/lang/Byte.html) types are projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var byte = new java.lang.Byte('1')
+var jsByteValue = byte.byteValue() // returns primitive byte, converted to Number
+```
+
+##### Short & Primitive short
+
+Both the primitive [short](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) and reference [java.lang.Short](http://docs.oracle.com/javase/7/docs/api/java/lang/Short.html) types are projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var short = new java.lang.Short('1')
+var jsShortValue = short.shortValue() // returns primitive short, converted to Number
+```
+
+##### Integer & Primitive int
+
+Both the primitive [int](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) and reference [java.lang.Integer](http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html) types are projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var int = new java.lang.Integer('1')
+var jsIntValue = int.intValue() // returns primitive int, converted to Number
+```
+
+##### Float & Primitive float
+
+Both the primitive [float](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) and reference [java.lang.Float](http://docs.oracle.com/javase/7/docs/api/java/lang/Float.html) types are projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var float = new java.lang.Float('1.5')
+var jsFloatValue = float.floatValue() // returns primitive float, converted to Number
+```
+
+##### Double & Primitive double
+
+Both the primitive [double](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) and reference [java.lang.Double](http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html) types are projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var double = new java.lang.Double('1.5')
+var jsDoubleValue = double.doubleValue() // returns primitive double, converted to Number
+```
+
+##### Long & Primitive long
+
+[java.lang.Long](http://docs.oracle.com/javase/7/docs/api/java/lang/Long.html) and its primitive equivalent are special types which are projected to JavaScript by applying the following rules:
+
+- If the value is in the interval (-2^53, 2^53) then it is converted to [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp)
+- Else a special object with the following characteristics is created:
+ - Has Number.NaN set as a prototype
+ - Has value property set to the string representation of the Java long value
+ - Its valueOf() method returns NaN
+ - Its toString() method returns the string representation of the Java long value
+
+```java
+public class TestClass {
+ public long getLongNumber54Bits(){
+ return 1 << 54;
+ }
+ public long getLongNumber53Bits(){
+ return 1 << 53;
+ }
+}
+```
+
+```js
+var testClass = new TestClass()
+var jsNumber = testClass.getLongNumber53Bits() // result is JavaScript Number
+var specialObject = testClass.getLongNumber54Bits() // result is the special object described above
+```
+
+##### Array
+
+Array in Java is a special [java.lang.Object](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html) that have an implicit Class associated. A Java Array is projected to JavaScript as a special JavaScript proxy object with the following characteristics:
+
+- Has length property
+- Has registered indexed getter and setter callbacks, which:
+ - If the array contains elements of type convertible to a JavaScript type, then accessing the i-th element will return a converted type
+ - If the array contains elements of type non-convertible to JavaScript, then accessing the i-th element will return a proxy object over the Java/Android type (see [Accessing APIs](#accessing-apis))
+
+```js
+var directory = new java.io.File('path/to/myDir')
+var files = directory.listFiles() // files is a special object as described above
+var singleFile = files[0] // the indexed getter callback is triggered and a proxy object over the java.io.File is returned
+```
+
+::: warning Note
+A Java Array is intentionally not converted to a JavaScript [Array](http://www.w3schools.com/jsref/jsref_obj_array.asp) for the sake of performance, especially when it comes to large arrays.
+:::
+
+##### Array of Objects
+
+Occasionally you have to create Java arrays from JavaScript. For this scenario we added method `create` to built-in JavaScript [`Array` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array). Here are some examples how to use `Array.create` method:
+
+```js
+// the following statement is equivalent to byte[] byteArr = new byte[10];
+var byteArr = Array.create('byte', 10)
+
+// the following statement is equivalent to String[] stringArr = new String[10];
+var stringArr = Array.create(java.lang.String, 10)
+```
+
+Here is the full specification for `Array.create` method
+
+```js
+Array.create(elementClassName, length)
+```
+
+```js
+Array.create(javaClassCtorFunction, length)
+```
+
+The first signature accepts `string` for `elementClassName`. This option is useful when you have to create Java array of primitive types (e.g. `char`, `boolean`, `byte`, `short`, `int`, `long`, `float` and `double`). It is also useful when you have to create Java jagged arrays. For this scenario `elementClassName` must be the standard JNI class notation. Here are some examples:
+
+```js
+// equivalent to int[][] jaggedIntArray2 = new int[10][];
+var jaggedIntArray2 = Array.create('[I', 10)
+
+// equivalent to boolean[][][] jaggedBooleanArray3 = new boolean[10][][];
+var jaggedBooleanArray3 = Array.create('[[Z', 10)
+
+// equivalent to Object[][][][] jaggedObjectArray4 = new Object[10][][][];
+var jaggedObjectArray4 = Array.create('[[[Ljava.lang.Object;', 10)
+```
+
+The second signature uses `javaClassCtorFunction` which must the JavaScript constructor function for a given Java type. Here are some examples:
+
+```js
+// equivalent to String[] stringArr = new String[10];
+var stringArr = Array.create(java.lang.String, 10)
+
+// equivalent to Object[] objectArr = new Object[10];
+var objectArr = Array.create(java.lang.Object, 10)
+```
+
+#### Array of Primitive Types
+
+The automatic marshalling works only for cases with arrays of objects. In cases where you have a method that takes an array of primitive types, you need to convert it as follows:
+
+```java
+public static void myMethod(int[] someParam)
+```
+
+Then yoy need to invoke it as follows:
+
+```js
+let arr = Array.create('int', 3)
+arr[0] = 1
+arr[1] = 2
+arr[2] = 3
+
+SomeObject.myMethod(arr) // assuming the method is accepting an array of primitive types
+```
+
+However there are some other helpful classes we can use to create a few other arrays of primitive types
+
+```js
+const byteArray = java.nio.ByteBuffer.wrap([1]).array()
+const shortArray = java.nio.ShortBuffer.wrap([1]).array()
+const intArray = java.nio.IntBuffer.wrap([1]).array()
+const longArray = java.nio.LongBuffer.wrap([1]).array()
+const floatArray = java.nio.FloatBuffer.wrap([1]).array()
+const doubleArray = java.nio.DoubleBuffer.wrap([1]).array()
+```
+
+##### Two-Dimensional Arrays of Primitive Types
+
+The above scenario gets more tricky with two-dimensional arrays. Consider a Java method that accepts as an argument a two-dimensional array:
+
+```java
+public static void myMethod(java.lang.Integer[][] someParam)
+```
+
+The marshalled JavaScript code will look like this:
+
+```js
+let arr = Array.create('[Ljava.lang.Integer;', 2)
+let elements = Array.create('java.lang.Integer', 3)
+elements[0] = new java.lang.Integer(1)
+elements[1] = new java.lang.Integer(2)
+elements[2] = new java.lang.Integer(3)
+arr[0] = elements
+
+SomeObject.myMethod(arr) // assuming the method is accepting a two-dimensional array of primitive types
+```
+
+##### Null
+
+The Java [null literal](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.7) (or null pointer) is projected to JavaScript [Null](https://www.w3schools.com/js/js_type_conversion.asp):
+
+```js
+var context = ...
+var button = new android.widget.Button(context);
+var background = button.getBackground(); // if there is no background drawable method will return JS null
+```
+
+##### Android Types
+
+All Android-declared types are projected to JavaScript using the Package and Class proxies as described in [Accessing APIs](#accessing-apis)
+
+#### Kotlin to Javascript Conversion
+
+The article lists the available types in Kotlin and how they are projected to JavaScript.
+
+Keep in mind that some of Kotlin's fundamental types are translated to a Java type by the Kotlin compiler when targeting Android or the JVM. Those types are the following:
+
+| **Kotlin non-nullable type** | **Java type** | **Kotlin nullable type** | **Java type** |
+| ---------------------------- | ---------------- | ------------------------ | ------------------- |
+| kotlin.Any | java.lang.Object | kotlin.Any? | java.lang.Object |
+| kotlin.String | java.lang.String | kotlin.String? | java.lang.String |
+| kotlin.Char | char | kotlin.Char? | java.lang.Character |
+| kotlin.Boolean | boolean | kotlin.Boolean? | java.lang.Boolean |
+| kotlin.Byte | byte | kotlin.Byte? | java.lang.Byte |
+| kotlin.Short | short | kotlin.Short? | java.lang.Short |
+| kotlin.Int | int | kotlin.Int? | java.lang.Integer |
+| kotlin.Long | long | kotlin.Long? | java.lang.Long |
+| kotlin.Float | float | kotlin.Float? | java.lang.Float |
+
+Although the conversion of Kotlin types in NativeScript is quite the same as the [Java conversion](#java-to-javascript-conversion), let's take a look at some examples.
+
+##### String & Character
+
+Both [kotlin.String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html) and [kotlin.Char](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/index.html) types are projected as JavaScript [String](http://www.w3schools.com/jsref/jsref_obj_string.asp):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithStringAndCharProperty()
+var str1 = kotlinClass.getStringProperty() // returns kotlin.String, converted to JS String
+var str2 = kotlinClass.getCharProperty() // returns kotlin.Char, converted to JS String
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithStringAndCharProperty {
+ val stringProperty: String = "string property"
+ val charProperty: Char = 'c'
+}
+```
+
+##### Boolean
+
+Kotlin's boolean type [kotlin.Boolean](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) is projected as JavaScript [Boolean](http://www.w3schools.com/jsref/jsref_obj_boolean.asp):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithBooleanProperty()
+var enabled = kotlinClass.getBooleanProperty() // returns Kotlin Boolean, converted to JS Boolean
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithBooleanProperty {
+ val booleanProperty: Boolean = false
+}
+```
+
+##### Byte
+
+Kotlin's byte type [kotlin.Byte](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-byte/index.html) is projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithByteProperty()
+var jsByteValue = kotlinClass.getByteProperty() // returns Kotlin Byte, converted to Number
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithByteProperty {
+ val byteProperty: Byte = 42
+}
+```
+
+##### Short
+
+Kotlin's short type [kotlin.Short](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-short/index.html) is projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithShortProperty()
+var jsShortValue = kotlinClass.getShortProperty() // returns Kotlin Short, converted to Number
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithShortProperty {
+ val shortProperty: Short = 42
+}
+```
+
+##### Integer
+
+Kotlin's integer type [kotlin.Int](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html) is projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithIntProperty()
+var jsIntValue = kotlinClass.getIntProperty() // returns Kotlin Int, converted to Number
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithIntProperty {
+ val intProperty: Int = 42
+}
+```
+
+##### Float
+
+Kotlin's float type [kotlin.Float](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-float/index.html) is projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithFloatProperty()
+var jsFloatValue = kotlinClass.getFloatProperty() // returns Kotlin Float, converted to Number
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithFloatProperty {
+ val floatProperty: Float = 42.0f
+}
+```
+
+##### Double
+
+Kotlin's double type [kotlin.Double](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-double/index.html) is projected as JavaScript [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithDoubleProperty()
+var jsDoubleValue = kotlinClass.getDoubleProperty() // returns Kotlin double, converted to Number
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithDoubleProperty {
+ val doubleProperty: Double = 42.0
+}
+```
+
+##### Long
+
+Kotlin's long type [kotlin.Long](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html) is a special type which is projected to JavaScript by applying the following rules:
+
+- If the value is in the interval (-2^53, 2^53) then it is converted to [Number](http://www.w3schools.com/jsref/jsref_obj_number.asp)
+- Else a special object with the following characteristics is created:
+ - Has Number.NaN set as a prototype
+ - Has value property set to the string representation of the Kotlin long value
+ - Its valueOf() method returns NaN
+ - Its toString() method returns the string representation of the Kotlin long value
+
+```kotlin
+package com.example
+
+class KotlinClassWithLongProperties {
+ val longNumber54Bits: Long
+ get() = (1 shl 54).toLong()
+ val longNumber53Bits: Long
+ get() = (1 shl 53).toLong()
+}
+```
+
+```js
+var kotlinClass = new com.example.KotlinClassWithLongProperties()
+var jsNumber = kotlinClass.getLongNumber53Bits() // result is JavaScript Number
+var specialObject = kotlinClass.getLongNumber54Bits() // result is the special object described above
+```
+
+##### Array
+
+Array in Kotlin is a special object that has an implicit Class associated. A Kotlin Array is projected to JavaScript as a special JavaScript proxy object with the following characteristics:
+
+- Has length property
+- Has registered indexed getter and setter callbacks, which:
+ - If the array contains elements of type convertible to a JavaScript type, then accessing the n-th element will return a converted type
+ - If the array contains elements of type non-convertible to JavaScript, then accessing the n-th element will return a proxy object over the Kotlin type (see [Accessing APIs](#accessing-apis))
+
+```js
+var kotlinClass = new com.example.KotlinClassWithStringArrayProperty()
+var kotlinArray = kotlinClass.getStringArrayProperty() // kotlinArray is a special object as described above
+var firstStringElement = kotlinArray[0] // the indexed getter callback is triggered and the kotlin.String is returned as a JS string
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithStringArrayProperty {
+ val stringArrayProperty: Array = arrayOf("element1", "element2", "element3")
+}
+```
+
+::: warning Note
+A Kotlin Array is intentionally not converted to a JavaScript [Array](http://www.w3schools.com/jsref/jsref_obj_array.asp) for the sake of performance, especially when it comes to large arrays.
+:::
+
+##### Creating arrays
+
+Occasionally you have to create Kotlin arrays from JavaScript. Because of the translation of the fundamental Kotlin types to Java types in Android, creating Kotlin array could be done the same way Java arrays are created. This is described in [Java to JavaScript](#java-to-javascript-conversion)
+
+##### Null
+
+The Kotlin null literal (or null pointer) is projected to JavaScript [Null](https://www.w3schools.com/js/js_type_conversion.asp):
+
+```js
+var kotlinClass = new com.example.KotlinClassWithNullableProperty()
+var nullableValue = kotlinClass.getNullableProperty() // if there is no value, the method will return JS null
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithNullableProperty() {
+ val nullableProperty: Any? = null
+}
+```
+
+##### Kotlin Types
+
+All Kotlin types are projected to JavaScript using the Package and Class proxies as described in [Accessing APIs](#accessing-apis)
+
+##### Kotlin Companion objects
+
+Kotlin's [companion objects](https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html#companion-objects) could be accessed in JavaScript the same way they can be accessed in Java - by accessing the `Companion` field:
+
+```js
+var companion = com.example.KotlinClassWithCompanion.Companion
+var data = companion.getDataFromCompanion()
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithCompanion {
+ companion object {
+ fun getDataFromCompanion() = "some data"
+ }
+}
+```
+
+##### Kotlin Object
+
+Kotlin's [objects](https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html#object-declarations) could be accessed in JavaScript the same way they can be accessed in Java - by accessing the INSTANCE field:
+
+```js
+var objectInstance = com.example.KotlinObject.INSTANCE
+var data = objectInstance.getDataFromObject()
+```
+
+```kotlin
+package com.example
+
+object KotlinObject {
+ fun getDataFromObject() = "some data"
+}
+```
+
+##### Accessing Kotlin properties
+
+Kotlin's [properties](https://kotlinlang.org/docs/reference/properties.html#properties-and-fields) could be accessed in JavaScript the same way they can be accessed in Java - by using their compiler-generated get/set methods. Non-boolean Kotlin properties could be used in NativeScript applications as JS fields as well.
+
+```js
+var kotlinClass = new com.example.KotlinClassWithStringProperty()
+
+var propertyValue = kotlinClass.getStringPropert()
+kotlinClass.setStringProperty('example')
+
+propertyValue = kotlinClass.stringProperty
+kotlinClass.stringProperty = 'second example'
+```
+
+```kotlin
+package com.example
+
+class KotlinClassWithStringProperty(var stringProperty: kotlin.String)
+```
+
+##### Accessing Kotlin package-level functions
+
+Currently using Kotlin [package-level functions](https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#package-level-functions) could not be achieved easily. In order to use a package-level function, the class where it's defined should be known. Let's take a look at an example:
+
+```js
+var randomNumber = com.example.FunctionsKt.getRandomNumber()
+```
+
+```kotlin
+package com.example
+
+fun getRandomNumber() = 42
+```
+
+In the example above, the class `FunctionsKt` is autogenerated by the Kotlin compiler and its name is based on the name of the file where the functions are defined. Kotlin supports annotating a file to have a user provided name and this simplifies using package-level functions:
+
+```js
+var randomNumber = com.example.UtilityFunctions.getRandomNumber()
+```
+
+```kotlin
+@file:JvmName("UtilityFunctions")
+package com.example
+
+fun getRandomNumber() = 42
+```
+
+##### Accessing Kotlin extension functions
+
+Currently using Kotlin extension functions could not be achieved easily. In order to use an extension function, the class where it's defined should be known. Also, when invoking it, the first parameter should be an instance of the type for which the function is defined. Let's take a look at an example:
+
+```js
+var arrayList = new java.util.ArrayList()
+arrayList.add('firstElement')
+arrayList.add('secondElement')
+com.example.Extensions.switchPlaces(arrayList, 0, 1)
+```
+
+```kotlin
+package com.example
+
+import java.util.ArrayList
+
+fun ArrayList.switchPlaces(firstElementIndex: Int, secondElementIndex: Int) {
+ val temp = this[firstElementIndex]
+ this[firstElementIndex] = this[secondElementIndex]
+ this[secondElementIndex] = temp
+}
+```
+
+In the example above, the class `ExtensionsKt` is autogenerated by the Kotlin compiler and its name is based on the name of the file where the functions are defined. Kotlin supports annotating a file to have a user provided name and this simplifies using package-level functions:
+
+```js
+var arrayList = new java.util.ArrayList()
+arrayList.add('firstElement')
+arrayList.add('secondElement')
+com.example.ExtensionFunctions.switchPlaces(arrayList, 0, 1)
+```
+
+```kotlin
+@file:JvmName("ExtensionFunctions")
+package com.example
+
+import java.util.ArrayList
+
+fun ArrayList.switchPlaces(firstElementIndex: Int, secondElementIndex: Int) {
+ val temp = this[firstElementIndex]
+ this[firstElementIndex] = this[secondElementIndex]
+ this[secondElementIndex] = temp
+}
+```
diff --git a/architecture-concepts/memory-management.md b/architecture-concepts/memory-management.md
new file mode 100755
index 00000000..3b5c21f3
--- /dev/null
+++ b/architecture-concepts/memory-management.md
@@ -0,0 +1,209 @@
+---
+title: Memory Management
+---
+
+## Memory Management
+
+NativeScript allows JavaScript code to be called from native and vice versa. It does so by creating bridging counterparts for each instance which must be exposed to the "other world" (native or JavaScript). These let developers access and consume the native APIs from JavaScript by:
+
+- implementing native interfaces or deriving from native classes in JavaScript
+- creating/accessing native instances and calling into their methods from JavaScript.
+
+In this article, we are explaining the lifecycle of JavaScript and native instances and show some troublesome conditions which may arise out of the complications of having two garbage collected runtimes (Android) or a garbage collected runtime and reference counting (iOS).
+
+## Terms
+
+_Disclaimer: These terms are not necessarily well established in the literature but we are introducing them for convenience in the following sections._
+
+- **native instance** - Objective-C/Swift class instance (iOS) or Java/Kotlin class instance (Android).
+
+- **reference counting** - the Objective-C runtime in iOS uses reference counting for lifetime management. Instances keep an internal counter which can be incremented and decremented. Each time a strong reference is set to point to an instance, the instance's reference count is incremented. Each time a strong reference is changed, the previous instance it pointed to has its reference count decremented. When the count reaches 0, the instance is deallocated.
+
+- **Garbage Collection (GC)** - garbage collection in general. When GC runs, it first block the threads to find all strong instances from the stack. Then resumes execution until the GC marks all reachable objects in a separate thread. Then blocks again the threads to complete the marking. And in the end finalizes and deallocates the detected unreachable instances. While the actual GC implementation may be much more sophisticated, all implementations in virtual machines used for UI aim at minimizing the time the main thread is blocked. The Android Java VM, Android's V8 and iOS's JavaScriptCore are the three state of the art virtual machines used by NativeScript, which have garbage collectors.
+
+- **weak/strong reference** - instances can reference each other. When there is a path in the graph of strong references from a root instance (one held by local variable on the stack, static field etc.) to another instance, the second one can not be garbage collected. Weak references on the other hand do not prevent their referent from being collected.
+
+- **splice** - let's introduce a new NativeScript term. We will call a splice the bond, made between a native instance and its representation in JavaScript by a JavaScript instance. In some cases it is possible that the splice is instantiated first in native (e.g. the iOS AppDelegate class, Android's Application, Activity and Fragment classes).
+
+The splices have a reference to a JavaScript instance and a native instance.
+
+- If the splice has a strong reference to an instance, it will prevent it from being collected by the GC.
+- If the splice has a weak reference to an instance, that instance can be collected if it is otherwise unreachable.
+- The splice itself will be deallocated if both the JavaScript and the native instances are collected.
+- The splice will be half-dead while one of its instances is alive and the other dead.
+
+The splices exhibit the following behavior:
+
+- Retrieve the native instance from a given JavaScript instance
+- Retrieve the JavaScript instance from a given native instance
+- Synchronize the life-cycle of the two instances
+- Proxy method calls, to and from, the JavaScript and native instances
+- Throw exceptions, when methods are called, while in half-dead state
+
+A splice is created:
+
+- When a native instance is returned from a constructor, method, property, block, anonymous interface, lambda etc. called from JavaScript.
+- When a native instance is passed as an argument to a constructor, method, property, block, anonymous interface, lambda etc. implemented in JavaScript.
+- When a native class extended in JavaScript is instantiated either in native or JavaScript.
+
+## iOS
+
+The Objective-C runtime has no GC and relies on reference counting instead. The _retain_ and _release_ calls of each Objective-C instance are intercepted by the iOS runtime. The Objective-C has association API that allows native objects to be assigned dynamically key-value pairs. JavaScriptCore has API to protect JavaScript instances that can be used to make them strong/weak (i.e. allow or deny them from being garbage collected). The _splice_ term here will refer to linking an Objective-C instance of a class with a JavaScript instance.
+
+Splice Lifecycle
+
+When a splice is made, it increases the ref-count of the Objective-C instance by 1, and if the ref-count is >1 the splice makes the JavaScript instance strong. From that point on:
+
+- If the Objective-C instance ref-count is incremented from 1 to 2, the splice makes its weak reference to the JavaScript instance strong.
+- If the Objective-C instance ref-count is decremented from 2 to 1, the splice makes its strong reference to the JavaScript instance to weak.
+- Only when the Objective-C instance's ref-count is 1, will the splice have weak reference to the JavaScript instance, thus rendering the JavaScript instance eligible for garbage collection. Then the GC will mark this JavaScript instance for collection if it fails to reach it from an alive JavaScript object. Afterwards, when the JavaScript instance is finalized by JSC, the splice will schedule a decrementation of the Objective-C instance's ref-count, eventually deallocating it and disposing the splice.
+
+### Properties of the Implementation
+
+#### Native Instances can Easily Leak
+
+You can make a reference cycle in Objective-C that will leak native and JavaScript instances, because the JavaScript GC does not traverse the native objects and fails to detect cycles. Native tools (Xcode, Instruments) can be used to detect and point to the leaking instances.
+
+#### Native Instances can be Prematurely Deallocated
+
+You can let instances be prematurely collected when using weak properties or APIs that involve methods such as _setTarget:selector:...._ They add the Objective-C instance as a native target, but through a weak Objective-C reference which doesn't increment the ref-count of the Objective-C instance. When the target ref-count remains 1 and the JavaScript GC collects the JavaScript instance of the splice, it will also deallocate the Objective-C instance. The annoying part is the code will work properly most of the time, but sometimes, due to the non-deterministic completion of the GC, it will cause the said deallocation and make the program throw an exception or crash.
+
+#### Half-Dead Splice
+
+When the JavaScript counterpart of a splice is collected, the native Objective-C instance is scheduled for deallocation. There is a very short time frame during which the native instance could be posted a message (as example - a method call on a delegate that is normally held in a weakref property). This will result in calling to an already collected JavaScript instance.
+
+#### Very Objective-C Friendly
+
+Overall the implementation is really Objective-C friendly and predictable. When working with native APIs it requires some additional care about memory management, but nothing more than general iOS knowledge. It is very UI friendly and does not introduce pauses on the main UI thread.
+
+####∫ Deep Hierarchies Die Hard
+The number of GC cycles needed to collect a linked list exposed from Obj-C to JavaScript is linear based on the numbers of nodes in the list.
+
+Take the following scenario (which is actually a real problem that has been solved in @nativescript/core):
+
+```
+Page -> StackPanel -> Button
+|.ios |.ios |.ios
+UIViewController UIView UIButton
+```
+
+When it is "Visible", the _UIViewController_ has its root view property pointing to the _UIView_, the _UIView_ has a collection holding a reference to the _UIButton_. Each of them has a JavaScript wrapper. While the visual tree is being presented, the Objective-C _UIViewController_, _UIView_ and _UIButton_ have reference counts of 2 and the JavaScript references are "protected" (meaning that the JavaScript GC will consider these objects to be roots and won't collect them).
+
+When "Navigated Away" from the page, the parent _UINavigationController_ will remove the _UIViewController_ and drop its reference count to 1, thus "unprotecting" its JavaScript wrapper, making it eligible for garbage collection.
+
+Then the next GC collects the Page, but the UIView will still have a reference count of 2 and its JavaScript wrapper will be protected.
+
+Here is what it takes to collect that whole tree:
+
+| | UIVIEWCONTROLLER | UIVIEW | UIBUTTON |
+| -------------- | ------------------ | ------------------ | ------------------ |
+| Visible | RC: 2, Protected | RC: 2, Protected | RC: 2, Protected |
+| Navigated Away | RC: 1, Unprotected | RC: 2, Protected | RC: 2, Protected |
+| GC Pass 1 | Collected | RC: 1, Unprotected | RC: 2, Protected |
+| GC Pass 2 | Collected | Collected | RC: 1, Unprotected |
+| GC Pass 3 | Collected | Collected | Collected |
+
+To prevent this multiple GCs requirement in order to free all objects, there's some additional logic implemented that separates the native views. When you remove the _Page_ from the visual tree it will remove the _UIButton_ from the _UIView_ and the _UIView_ from the _UIViewController_ achieving this:
+
+| | UIVIEWCONTROLLER | UIVIEW | UIBUTTON |
+| -------------- | ------------------ | ------------------ | ------------------ |
+| Visible | RC: 2, Protected | RC: 2, Protected | RC: 2, Protected |
+| Navigated Away | RC: 1, Unprotected | RC: 1, Unprotected | RC: 1, Unprotected |
+| GC Pass 1 | Collected | Collected | Collected |
+
+## Android
+
+In Android both the Java and the JavaScript VMs are GC based. The Android Java VM has a limited public API to subscribe for GC events, while in the V8 there is a richer API to subscribe for GC prologue and epilogue, and also allows us to subscribe for notifications when a JavaScript instance is marked for collection, letting us optionally revive it if we discover that it's still being referenced from outside.
+
+### Splice Life-Cycle
+
+The Android splice has two flavors:
+
+- It is considered to "have implementation object" in cases when:
+ - A splice is created for an "anonymous interface", such as _new ClickListener({ ... })_.
+ - A splice is created for an "extended native class", such as _var MyView = View.extends({ ... });_ _var myView = new MyView();_.
+- It is considered **not to** "have implementation object" in cases when:
+ - A splice is created for _var button = new android.widget.Button(...)_ where a native class is instantiated.
+ - A splice is created for _var i = anAndroidObject.getValue()_ when Java instance is returned by the getValue() method.
+
+When a splice is created
+
+- The splice has a strong reference to the Java instance, and the Java instance can not be collected by the Android Java VM GC
+
+On V8 GC collection phase:
+
+- From the JavaScript instances of each splice that **has** an implementation object will be traversed all other reachable JavaScript instances. For each of these reachable JavaScript objects:
+ - The splice will be marked as "implementation reachable" if the reached object is an implementation object
+ - Otherwise it is ignored.
+
+After that all splices are processed according to these cases:
+
+- If the JavaScript instance is marked for collection and has no implementation object, then the JavaScript instance is left to be collected and the reference to the Java instance is made weak.
+- If the JavaScript instance is marked for collection, has an implementation object and the Java instance is weakly referenced, then:
+ - If the Java object is alive, the JavaScript instance is revived.
+ - If the Java object is dead, the JavaScript instance is left to be collected.
+- If JavaScript instance is marked for collection and has an implementation object and the Java instance is strongly referenced, then:
+ - The JavaScript instance of the splice is revived.
+ - If the splice was not marked "implementation reachable" in the previous step, the reference to its Java instance is made weak.
+
+### Properties of the Implementation
+
+#### Premature Collection
+
+Unlike iOS, both the Java and JavaScript in the Android runtime are managed. The native framework rarely uses weak references, so premature collection can hardly ever be observed. The most common issues with GC for Android are half-dead splices.
+
+#### Leaks
+
+Memory leaks are rare. If there is a pool of unreachable splices from either Java or JavaScript, at some point the V8 GC will notify the JavaScript instances that they are marked for collection, then the reference to the Java counterpart will be made weak. Then the next Android VM GC will collect the Java instances and the V8 GC after that will collect the JavaScript instances (because the Java counterparts will be dead).
+
+#### Half-Dead Splice
+
+Since collection is driven by the garbage collectors it is possible to hold a weak reference to the JavaScript instance of a splice. After a V8 GC, the splice can make the reference to the Java instance weak allowing the Android VM GC to collect it. Then, if before the next V8 GC the JavaScript instance is obtained from the weak reference and its methods are called, it will result in accessing a half-dead splice (since the Java counterpart is dead already). The error reported by the runtime points out that we've failed to find an object for a given id. These problems are perceived as random and are quite hard to reproduce.
+
+#### Splices Die Fast
+
+Multiple splices and JavaScript instances can be created for a single Java object, properties may be lost.
+
+Splices with no implementation object, can have their JavaScript instances collected easily. Consider the following sequence of executions:
+
+- A splice is created by getting an existing Java instance in JavaScript
+- Some work is performed with it and new JavaScript properties are assigned to it
+- The reference to the JavaScript instance is destroyed
+- V8 collects the JavaScript instance during GC and the splice is deallocated
+- For the second time the same Java instance is obtained and a new splice with a new JavaScript instance is created and returned
+
+As a result, the property assigned to the first JavaScript object is lost, because the new instance can retrieve only the Java properties of its corresponding native object.
+
+#### Splices Die Hard
+
+Working with short lived big objects can easily trigger out-of-memory crashes. Due to the life cycle of the Android splice, it requires a V8 GC with subsequent Android VM GC to dispose big native instances (such as bitmaps).
+
+#### Java Friendly
+
+Overall the implementation is really Java friendly. It rarely requires additional knowledge about the inner workings of the runtime.
+
+### Outstanding Problems
+
+Here are some of the problems that still need to be addressed in the order of importance:
+
+- During a GC, the extra work required to traverse the JavaScript heap causes relatively big pauses on the main thread. E.g. for an Angular + {N} app with snapshot, each V8 GC can take up to half a second on a modern phone. We have introduced the **markingMode: "none"** option that involves no object graph traversing but has its pitfalls.
+ The cases of half-dead splices, although rare, are very hard to reproduce, track, debug, and fix.
+- Big objects take several V8 and Android VM GC passes to release, we could provide API to explicitly state that such objects will no longer be used and the reference to the Java instance will be made weak.
+- Regular splice objects, with no implementation object, cannot be extended with simple JavaScript properties. It would be useful if we could extend their lifetime to match the lifetime of the Java object.
+
+### Common tips
+
+Due to the internal memory management of objects in the runtimes, there are cases where big native objects might live longer than necessary. This might happen if the JS garbage collector does not run for a long time after the object has become eligible for GC. As a result, a strong reference for this object will remain on the native side.
+
+One way to solve this issue is to trigger multiple garbage collections - in JS/TS and in the native side (in case of running on Android). This, however, is not a cheap operation. Triggering garbage collections by hand is not only slow but can disrupt normal garbage management.
+
+Another way to solve the issue is by using the _releaseNativeCounterpart_ function which takes as an argument an instance of a native class and removes its strong reference in the runtimes. By doing this, the native garbage collector in Android can remove the possibly heavy native object on its next run if it considers it dead. In iOS, as there is no garbage collector, using this function, the reference count of the native object would be decreased by one and if there are no other usages of this object - it would be deleted.
+
+If after using the releaseNativeCounterpart function you try to use the native object in JS/TS, the behaviour is undefined, so use this function if you are sure the object would not be used again.
+
+Example usage of the _releaseNativeCounterpart_ function in JS/TS:
+
+```
+const heavyNativeObject = new com.native.HeavyObject();
+releaseNativeCounterpart(heavyNativeObject); // all usages of heavyNativeObject after this line would have undefined behaviour
+```
diff --git a/architecture-concepts/metadata.md b/architecture-concepts/metadata.md
new file mode 100755
index 00000000..d202cb55
--- /dev/null
+++ b/architecture-concepts/metadata.md
@@ -0,0 +1,629 @@
+## Metadata
+
+To allow JavaScript code to call into native iOS or Android code both NativeScript runtimes need the so called **_metadata_**. It contains all the necessary information about each of the supported native classes, interfaces, protocols, structures, enumerations, functions, variables, etc. and is generated at build time by examining the native libraries from the iOS/Android operating systems' SDKs and any third-party libraries and frameworks that are used by the {N} application.
+
+### Metadata Filtering
+
+By default NativeScript includes all supported entities in the metadata. This allows app and plugin authors to freely call any native API from JavaScript. While it is benefitial during development, in some cases having metadata for all the APIs is undesirable. There could be security implications involved (mentioning names of entities that shouldn't be known in the metadata binary files for example); performance could be degraded at runtime (due to larger metabase which has to be consulted when an unknown entry is encountered or at startup); or app size could increase due to unnecessary metadata which is never used.
+
+To give developers control over what to be included or not in the generated metadata there's support for black and whitelisting symbols by their native name.
+
+### Metadata filtering rules in plugins
+
+Plugins can declare their list of APIs that are called from JavaScript using a file named `native-api-usage.json`, located in each of the platform directories (`platforms/android` or `platforms/ios`). Its format is similar to:
+
+```json
+{
+ "uses": ["java.util:List"]
+}
+```
+
+### Metadata filtering rules in apps
+
+Applications have the final word of what filtering will be applied to metadata. They provide similar `native-api-usage.json` files, located in `App_Resources/Android` and `App_Resources/iOS`, having the following format:
+
+```json
+{
+ "whitelist-plugins-usages": true,
+ "whitelist": ["java.util:Base64*"],
+ "blacklist": ["java.util:Locale*"]
+}
+```
+
+### Rules syntax
+
+Each list comprises of pattern entries with the following characteristics:
+
+- Entries are of the form `[:pattern2]`
+- On Android, **_pattern1_** is matched against Java package names, while the optional **_pattern2_** -- against classes, interfaces, enums.
+- On iOS, **_pattern1_** is matched against Clang module/submodule names, while the optional **_pattern2_** -- against structs, global functions, enums, Objective-C interfaces, protocols, categories, constants, etc.
+- Patterns support wildcards (**"\*"** - any number of characters and **"?"** - any single character).
+- An unspecified or empty pattern is equivalent to being set to **"\*"** (matching everything)
+
+### Rules semantics
+
+After analyzing the filtering rules for a platform, {N} CLI builds final whitelist and blacklist files and outputs them in the native project to be used by the corresponding metadata generator. The blacklist is always equal to the one specified by the app. While the whitelist depends on the `whitelist-plugins-usages` flag:
+
+- If it is `true`, the final whitelist is a concatenation of all plugins' usage lists with the app's whitelist
+- Otherwise, it is equal to the app's whitelist
+
+These two lists unambiguously determine how filtering is performed:
+
+1. If the whitelist is empty, then everything is considered whitelisted by default
+2. If it contains at least one rule, only entities matching a rule are considered whitelisted
+3. All entities which are not whitelisted or match a rule in the blacklist are stripped from metadata
+4. All other entities are included in the metadata
+
+### Examples
+
+Sample filtering specifications can be found in `@nativescript/core` plugin's repository:
+
+- [Android API usage list](https://github.com/NativeScript/NativeScript/blob/master/packages/core/platforms/android/native-api-usage.json)
+- [iOS API usage list](https://github.com/NativeScript/NativeScript/blob/master/packages/core/platforms/ios/native-api-usage.json)
+
+### Troubleshooting
+
+Missing metadata entities could result in bugs at runtime. For example, if a native class has been accidentally filtered out, its constructor function will be `undefined` and this will lead to an exception when its attempted to be called. Figuring out what is the reason for something being `undefined` could be quite difficult because the reasons can vary. To check whether metadata filtering is to blame or not you should examine metadata generator's verbose logs after a successful build:
+
+- On iOS they are located in `platforms/ios/build/-/metadata-generation-stderr-.txt` (e.g. `platforms/ios/build/Debug-iphonesimulator/metadata-generation-stderr-x86_64.txt`);
+- On Android they are located in `platforms/android/build-tools/buildMetadata.log`
+
+For each global symbol that is discovered by the generator, there should be a line providing information whether it was included in metadata or not, and which rules or what exception caused this. Examples:
+
+- `verbose: Blacklisted kCFBuddhistCalendar from CoreFoundation.CFLocale (disabled by 'CoreFoundation*:*')` - when there are no whitelist rules a blacklisted symbol will show only the rule which disabled it
+- `verbose: Blacklisted NSString from Foundation.NSString` - when there is at least one whitelist rule, some blacklisted symbols will not specify a rule. This means that the symbol didn't match any of the whitelist rules.
+- `verbose: Blacklisted PHImageContentModeDefault from Photos.PhotosTypes (enabled by 'Photos.PhotosTypes:*', disabled by 'Photos.PhotosTypes:PHImageContentMode*')`, `verbose: Blacklisted String from java.lang (enabled by java.lang:*, disabled by java.lang:String)` - a blacklisted entry which matches both a whitelist rule and a blacklist rule will specify both.
+- `verbose: Included NSObject from ObjectiveC.NSObject` - when there are no whitelist rules an included symbol won't specify a rule which caused it to be included
+- `verbose: Included PHCollectionListType from Photos.PhotosTypes (enabled by 'Photos.PhotosTypes:*')`, `verbose: Included StrictMath from java.lang (enabled by java.lang:*)` - when a symbol is included because it matched a rule from the whitelist (and didn't match any from the blacklist) it will print that rule
+- `verbose: Exception [Name: 'vfwprintf', JsName: 'vfwprintf', Module: 'Darwin.C.wchar', File: '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk/usr/include/wchar.h'] : Can't create type dependency. --> [Type Decayed] : Can't create type dependency. --> [Type Typedef] : VaList type is not supported.` - if a symbol is not included because it isn't supported for some reason it will be stated in the logged exception. In this case the symbol cannot be used from JavaScript because {N} doesn't support calling functions with variable argument lists.
+- `verbose: Exception [Name: 'GLKVector3Make', JsName: 'GLKVector3Make', Module: 'GLKit.GLKVector3', File: '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.2.sdk/System/Library/Frameworks/GLKit.framework/Headers/GLKVector3.h'] : Can't create type dependency. --> [Type Typedef] : Can't create type dependency. --> [Type Elaborated] : Can't create type dependency. --> [Type Record] : The record is an union.` - Another example of an unsupported symbol, this time the reason is that `union`s are unsupported
+
+## Android Metadata
+
+The NativeScript Metadata is the mapping between the JavaScript and the Android world. Besides a full list with all the available classes and methods, the metadata contains the [JNI](http://developer.android.com/training/articles/perf-jni.html) signature for each accessible Android method/field. It is pre-generated, in a binary format, and embedded in the application package (apk), storing the minimal required information thus providing small size and highly efficient read access. The generation process uses bytecode reading to parse all publicly available types in the Android libraries supplied to the NativeScript project. The generator works as part of the Android build process, meaning that no user interaction is required for it to work.
+
+![Metadata](/assets/images/metadata_diagram.png)
+
+### Metadata API Level
+
+Only Android public APIs (**including those of any plugins added to the project**) present in the metadata will be accessible in JavaScript/TypeScript. That means, if an application is built with metadata for API level 23 (Android Marshmallow 6.0 – 6.0.1), the application user might have problems when running the application on an older device, for example with API levels 17 through 19 (Android KitKat 4.4 – 4.4.4).
+
+Metadata is built automatically for the application. The metadata API level, or simply put, what API level the metadata is built for, is determined by the `--compileSdk` flag passed to the build. By default the nativescript CLI automatically detects the highest Android API level installed on the developer's machine and passes it to the build implicitly. This `--compileSdk` flag can be supplied explicitly when starting a build: `ns run android --compileSdk=1`.
+
+#### Metadata Limitations
+
+Let's look at the Android [TextView](https://developer.android.com/reference/android/widget/TextView.html).
+In API level 21 a method called `getLetterSpacing` was added. What that means is, an application developer can use the `getLetterSpacing` method only on two conditions:
+
+- The built metadata is >= 21
+- The device that the application will be running on is >= 21
+
+#### Possible Implications When Working With Android APIs
+
+##### Implication A: Building against lower API level.
+
+If an application is built with `--compileSdk` flag pointing to a lower Android API level, for example 19, the generated metadata will also be for API level 19. In that case making calls to API in Levels 21 and up will not be possible, because the metadata comprises of meta information about API level <= 19.
+
+This problem is easily solved by not specifying a `--compileSdk` flag and using the default behavior.
+
+##### Implication B: Building against higher API level.
+
+What happens when an application is built with higher API level(e.g. 23), but runs on a device with a lower API level(e.g. 20)?
+First the metadata is built for API level 23. If the javascript code calls a method introduced after API level 20 the Android runtime will try to call this method because it will recognize it in the metadata, but when the actual native call is made on the lower level device, an exception will be thrown because this method won't be present on the device.
+
+This problem is solved by detecting the API level at run-time and using the available API.
+
+Detecting the API Level in JavaScript:
+
+```js
+if (android.os.Build.VERSION.SDK_INT >= 21) {
+ // your api level-specific code
+}
+```
+
+### Accessing APIs
+
+One of NativeScript's strongest capabilities is the access to Android (also referred to as **'Java/Kotlin'** or **'native'**) APIs inside JavaScript/TypeScript. That's possible thanks to build-time generated [Metadata](#metadata) chunks which hold the information about the public classes from the Android SDK, Android support libraries, and any other Android libraries which may be imported into your Android NativeScript project.
+
+::: warning Note
+'Android classes' and 'Java/Kotlin classes' are used interchangeably throughout the article to refer to classes in the Java/Kotlin programming language.
+:::
+
+#### Access Android Packages
+
+The [Android packages](https://developer.android.com/reference/packages.html) are available in the JavaScript/TypeScript global context and are the entry point for accessing Android APIs. Think of them as of TypeScript/C# namespaces, or the way to access sets of classes. For example, the `android.view` package grants access to classes like `android.view.View` - the base of all view elements in Android.
+
+In order to access a particular class in JavaScript/TypeScript the full package name leading up to the class name needs to be specified, or you may end up working with `undefined` variables.
+
+- [java.lang](http://developer.android.com/reference/java/lang/package-summary.html)
+- [android](http://developer.android.com/reference/android/package-summary.html)
+- [android.view](http://developer.android.com/reference/android/view/package-summary.html)
+- etc.
+
+The above is accessed in JavaScript like:
+
+```js
+const javaLangPkg = java.lang
+const androidPkg = android
+const androidViewPkg = android.view
+
+// access classes from inside the packages later on
+
+const View = androidViewPkg.View
+// or
+const View = android.view.View
+
+const Object = javaLangPkg.Object // === java.lang.Object;
+```
+
+To find out the package name of an Android class, refer to the [Android SDK Reference](https://developer.android.com/reference/packages.html), or to the supplied API Reference of a plugin, when importing 3rd-party Android components into your project.
+
+For example, if you need to work with the Google API for Google Maps, after following the installation guide, you may need to access packages from the plugin like `com.google.android.gms.maps`, which you can find a reference for at [Google APIs for Android Reference](https://developers.google.com/android/reference/com/google/android/gms/maps/package-summary)
+
+::: warning Note
+To have access and Intellisense for the native APIs with **NativeScript + TypeScript** or **NativeScript + Angular** projects, you have to add a dev dependency to `@nativescript/types`. More details about accessing native APIs with TypeScript can be found [here]({% slug access-native-apis %}#intellisense-and-access-to-native-apis-via-typescript).
+:::
+
+::: warning Note
+**(Experimental)** Alternatively, to get Intellisense for the native APIs based on the available Android Platform SDK and imported Android Support packages (added by default to your Android project), supply the `--androidTypings` flag with your `ns run | build android` command. The resulting `android.d.ts` file can then be used to provide auto-completion.
+:::
+
+::: warning Note
+You cannot use APIs that are not present in the metadata. By default, if `--compileSdk` argument isn't provided while building, metadata will be built against the latest Android [Platform SDK](https://developer.android.com/about/versions/nougat/index.html) installed on the workstation. See [metadata limitations](#metadata-limitations).
+:::
+
+#### Access Android Classes
+
+Classes ([See OOP](https://docs.oracle.com/javase/tutorial/java/concepts/)) are the schematics to producing building blocks (Objects) in Android, as such, they are used to represent almost everything you see, as well as what you don't see, in an Android application - the Android layouts are objects built from classes, the buttons and text views also have class representations. Classes in Java and Kotlin have unique identifiers denoted by the full package name (see above), followed by the actual class name (usually capitalized - see above - 'View')
+
+Accessing classes in Android you would normally add an `import` statement at the beginning of the Java/Kotlin file, to allow referring to the class only by its name. If the developer decides, they may be as expressive as possible by using the full class identifier too:
+
+```java
+package my.awesome.application;
+
+import android.view.View;
+
+public class ... {
+ public static void staticMethod(context) {
+ View newView = new View(context);
+ // or
+ android.view.View newView2 = new android.view.View(context);
+ }
+}
+```
+
+Accessing Android classes, in the JavaScript/TypeScript of a NativeScript application, is kept as close to the original Java syntax as the JavaScript language allows:
+
+```js
+function arbitraryFunction(context) {
+ // 'context' is a JavaScript wrapper (Proxy - see below) for the underlying android.content.Context Java instance
+ const View = android.view.View
+
+ const newView = new View(context)
+ // or
+ const newView2 = new android.view.View(context)
+
+ // newView and newView2 will be JavaScript wrappers (Proxies - see below) for the created Java android.view.View objects
+}
+```
+
+#### Proxies
+
+The JavaScript objects that lie behind the Android APIs are called _Proxies_. There are two types of proxies:
+
+#### Package Proxy
+
+Provides access to the classes, interfaces, constants and enumerations within each package. See `java.lang`.
+
+#### Class Proxy
+
+Represents a thin wrapper over a class or an interface and provides access to its methods and fields. From a JavaScript perspective this type of proxy may be considered as a constructor function. For example `android.view.View` is a class proxy.
+
+The result of the constructor calls (`new ...()`) will create native `android.view.View` instances on the Android side and a special hollow Object on the JavaScript side. This special object knows how to invoke methods and access fields on the corresponding native instance. For example we may retrieve the path value of the above created `File` using the corresponding `File` class API like:
+
+#### Access Methods, Fields and Constants
+
+Thanks to the 'proxying' system, Java/Kotlin methods and fields can be accessed through the JavaScript wrappers of the native instances. For example, you may retrieve the result of a method call to the Java instance:
+
+```js
+const javaObj = new java.lang.Object()
+
+// result is `int` in Java, marshalled to a JavaScript number
+const javaObjHashCode = javaObj.hashCode()
+
+// prints out the hashCode number
+console.log(javaObjHashCode)
+```
+
+Public and private members, as well as static fields of an instance, or Java/Kotlin classes can also be accessed. The [android.view.View](https://developer.android.com/reference/android/view/View.html) class will be used below:
+
+```js
+// retrieve context
+const context = ...;
+const newView = new android.view.View(context);
+
+// public member call to 'public void clearFocus()' as declared in Android
+newView.clearFocus();
+
+// public static field access to 'public static final SCALE_X' as declared in Android
+let newViewScaleX = newView.SCALE_X;
+
+// public static field access to `FOCUS_UP` - represents an integer as declared in the Android source
+const focusUpDirection = android.view.View.FOCUS_UP;
+
+// public member call to 'public View focusSearch(int direction)'
+let foundView = newView.focusSearch(android.view.View.FOCUS_UP);
+
+// static method call to 'public static int generateViewId()' - generates a random integer suitable for Android Views
+const randomViewId = android.view.View.generateViewId();
+```
+
+#### Extend Classes and Interfaces
+
+For a comprehensive guide on extending classes and implementing interfaces through JavaScript/TypeScript check out [the dedicated article](https://v7.docs.nativescript.org/core-concepts/android-runtime/binding-generator/extend-class-interface.html).
+
+
+
+#### Full-fledged Example
+
+Let's take a sample Android code, and transcribe it to JavaScript/TypeScript.
+
+The following code (courtesy of [startandroid.ru](http://startandroid.ru/en/lessons/220-lesson-16-creating-layout-programmatically-layoutparams.html)) creates an Android layout, and adds a couple Button and TextView elements:
+
+```java
+public class MainActivity extends Activity {
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // creating LinearLayout
+ LinearLayout linLayout = new LinearLayout(this);
+ // specifying vertical orientation
+ linLayout.setOrientation(LinearLayout.VERTICAL);
+ // creating LayoutParams
+ LayoutParams linLayoutParam = new LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT
+ );
+ // set LinearLayout as a root element of the screen
+ setContentView(linLayout, linLayoutParam);
+
+ LayoutParams lpView = new LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ );
+
+ TextView tv = new TextView(this);
+ tv.setText("TextView");
+ tv.setLayoutParams(lpView);
+ linLayout.addView(tv);
+
+ Button btn = new Button(this);
+ btn.setText("Button");
+ linLayout.addView(btn, lpView);
+
+
+ LinearLayout.LayoutParams leftMarginParams = new LinearLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ );
+ leftMarginParams.leftMargin = 50;
+
+ Button btn1 = new Button(this);
+ btn1.setText("Button1");
+ linLayout.addView(btn1, leftMarginParams);
+
+
+ LinearLayout.LayoutParams rightGravityParams = new LinearLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ );
+ rightGravityParams.gravity = Gravity.RIGHT;
+
+ Button btn2 = new Button(this);
+ btn2.setText("Button2");
+ linLayout.addView(btn2, rightGravityParams);
+ }
+}
+```
+
+```kotlin
+class MainKotlinActivity: Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ // creating LinearLayout
+ val linLayout = LinearLayout(this)
+ // specifying vertical orientation
+ linLayout.orientation = LinearLayout.VERTICAL
+ // creating LayoutParams
+ val linLayoutParam = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
+ // set LinearLayout as a root element of the screen
+ setContentView(linLayout, linLayoutParam)
+
+ val lpView = LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ )
+
+ val tv = TextView(this)
+ tv.text = "TextView"
+ tv.layoutParams = lpView
+ linLayout.addView(tv)
+
+ val btn = Button(this)
+ btn.text = "Button"
+ linLayout.addView(btn, lpView)
+
+
+ val leftMarginParams = LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ )
+ leftMarginParams.leftMargin = 50
+
+ val btn1 = Button(this)
+ btn1.text = "Button1"
+ linLayout.addView(btn1, leftMarginParams)
+
+
+ val rightGravityParams = LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ )
+ rightGravityParams.gravity = Gravity.RIGHT
+
+ val btn2 = Button(this)
+ btn2.text = "Button2"
+ linLayout.addView(btn2, rightGravityParams)
+ }
+}
+```
+
+```js
+const MainActivity = android.app.Activity.extend('my.application.name.MainActivity', {
+ onCreate: function (savedInstanceState) {
+ super.onCreate(savedInstance)
+
+ // creating LinearLayout
+ let linLayout = new android.widget.LinearLayout(this)
+ // specifying vertical orientation
+ linLayout.setOrientation(android.widget.LinearLayout.VERTICAL)
+ // creating LayoutParams - accessing static class LayoutParams of LinearLayout
+ let linLayoutParam = new android.widget.LinearLayout.LayoutParams(
+ android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
+ android.widget.LinearLayout.LayoutParams.MATCH_PARENT
+ )
+ // set LinearLayout as a root element of the screen
+ this.setContentView(linLayout, linLayoutParam)
+
+ let lpView = new android.widget.LinearLayout.LayoutParams(
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT,
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
+ )
+
+ let tv = new android.widget.TextView(this)
+ tv.setText('TextView')
+ tv.setLayoutParams(lpView)
+ linLayout.addView(tv)
+
+ let btn = new android.widget.Button(this)
+ btn.setText('Button')
+ linLayout.addView(btn, lpView)
+
+ let leftMarginParams = new android.widget.LinearLayout.LayoutParams(
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT,
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
+ )
+ leftMarginParams.leftMargin = 50
+
+ let btn1 = new android.widget.Button(this)
+ btn1.setText('Button1')
+ linLayout.addView(btn1, leftMarginParams)
+
+ let rightGravityParams = new android.widget.LinearLayout.LayoutParams(
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT,
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
+ )
+ rightGravityParams.gravity = android.view.Gravity.RIGHT
+
+ let btn2 = new android.widget.Button(this)
+ btn2.setText('Button2')
+ linLayout.addView(btn2, rightGravityParams)
+ }
+})
+```
+
+```typescript
+@JavaProxy("my.application.name.MainActivity");
+class MainActivity extends android.app.Activity {
+ constructor() {
+ super();
+
+ return global.__native(this);
+ }
+
+ onCreate(savedInstanceState) {
+ super.onCreate(savedInstance);
+
+ // creating LinearLayout
+ let linLayout = new android.widget.LinearLayout(this);
+ // specifying vertical orientation
+ linLayout.setOrientation(android.widget.LinearLayout.VERTICAL);
+ // creating LayoutParams - accessing static class LayoutParams of LinearLayout
+ let linLayoutParam = new android.widget.LinearLayout.LayoutParams(
+ android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
+ android.widget.LinearLayout.LayoutParams.MATCH_PARENT
+ );
+ // set LinearLayout as a root element of the screen
+ this.setContentView(linLayout, linLayoutParam);
+
+ let lpView = new android.widget.LinearLayout.LayoutParams(
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT,
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
+ );
+
+ let tv = new android.widget.TextView(this);
+ tv.setText("TextView");
+ tv.setLayoutParams(lpView);
+ linLayout.addView(tv);
+
+ let btn = new android.widget.Button(this);
+ btn.setText("Button");
+ linLayout.addView(btn, lpView);
+
+
+ let leftMarginParams = new android.widget.LinearLayout.LayoutParams(
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT,
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
+ );
+ leftMarginParams.leftMargin = 50;
+
+ let btn1 = new android.widget.Button(this);
+ btn1.setText("Button1");
+ linLayout.addView(btn1, leftMarginParams);
+
+
+ let rightGravityParams = new android.widget.LinearLayout.LayoutParams(
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT,
+ android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
+ );
+ rightGravityParams.gravity = android.view.Gravity.RIGHT;
+
+ let btn2 = new android.widget.Button(this);
+ btn2.setText("Button2");
+ linLayout.addView(btn2, rightGravityParams);
+ }
+};
+```
+
+The NativeScript code can further be shortened, and it starts to look a lot like Java:
+
+```js
+const LinearLayout = android.widget.LinearLayout
+const LayoutParams = android.widget.LinearLayout.LayoutParams
+const TextView = android.widget.TextView
+const Button = android.widget.Button
+const Gravity = android.view.Gravity
+
+const MainActivity = android.app.Activity.extend('my.application.name.MainActivity', {
+ onCreate: function (savedInstanceState) {
+ super.onCreate(savedInstance)
+
+ // creating LinearLayout
+ let linLayout = new LinearLayout(this)
+ // specifying vertical orientation
+ linLayout.setOrientation(LinearLayout.VERTICAL)
+ // creating LayoutParams
+ let linLayoutParam = new LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT
+ )
+ // set LinearLayout as a root element of the screen
+ setContentView(linLayout, linLayoutParam)
+
+ let lpView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
+
+ let tv = new TextView(this)
+ tv.setText('TextView')
+ tv.setLayoutParams(lpView)
+ linLayout.addView(tv)
+
+ let btn = new Button(this)
+ btn.setText('Button')
+ linLayout.addView(btn, lpView)
+
+ let leftMarginParams = new LinearLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ )
+ leftMarginParams.leftMargin = 50
+
+ let btn1 = new Button(this)
+ btn1.setText('Button1')
+ linLayout.addView(btn1, leftMarginParams)
+
+ let rightGravityParams = new LinearLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ )
+ rightGravityParams.gravity = Gravity.RIGHT
+
+ let btn2 = new Button(this)
+ btn2.setText('Button2')
+ linLayout.addView(btn2, rightGravityParams)
+ }
+})
+```
+
+```typescript
+const LinearLayout = android.widget.LinearLayout;
+const LayoutParams = android.widget.LinearLayout.LayoutParams;
+const TextView = android.widget.TextView;
+const Button = android.widget.Button;
+const Gravity = android.view.Gravity;
+
+@JavaProxy("my.application.name.MainActivity");
+class MainActivity extends android.app.Activity {
+ constructor() {
+ super();
+
+ return global.__native(this);
+ }
+
+ onCreate: function (savedInstanceState) {
+ super.onCreate(savedInstance);
+
+ // creating LinearLayout
+ let linLayout = new LinearLayout(this);
+ // specifying vertical orientation
+ linLayout.setOrientation(LinearLayout.VERTICAL);
+ // creating LayoutParams
+ let linLayoutParam = new LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT
+ );
+ // set LinearLayout as a root element of the screen
+ setContentView(linLayout, linLayoutParam);
+
+ let lpView = new LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ );
+
+ let tv = new TextView(this);
+ tv.setText("TextView");
+ tv.setLayoutParams(lpView);
+ linLayout.addView(tv);
+
+ let btn = new Button(this);
+ btn.setText("Button");
+ linLayout.addView(btn, lpView);
+
+
+ let leftMarginParams = new LinearLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ );
+ leftMarginParams.leftMargin = 50;
+
+ let btn1 = new Button(this);
+ btn1.setText("Button1");
+ linLayout.addView(btn1, leftMarginParams);
+
+
+ let rightGravityParams = new LinearLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ );
+ rightGravityParams.gravity = Gravity.RIGHT;
+
+ let btn2 = new Button(this);
+ btn2.setText("Button2");
+ linLayout.addView(btn2, rightGravityParams);
+ }
+});
+```
+
+## iOS Metadata
+
+This is our own custom data format for listing the iOS APIs we are aware of (may process). It stores the minimal required information and provides small size and highly efficient read access. The iOS supports type introspection to some extent but along with the C APIs embedded all the way in the native APIs we had to store a lot of extra information. The Metadata is pre-generated at compile time from the SDK header files and embedded in the application package (ipa).
diff --git a/architecture-concepts/mvvm-pattern.md b/architecture-concepts/mvvm-pattern.md
new file mode 100755
index 00000000..afbecc03
--- /dev/null
+++ b/architecture-concepts/mvvm-pattern.md
@@ -0,0 +1,21 @@
+---
+title: MVVMM Pattern
+---
+
+## Mvvm Pattern
+
+MVVM ([Model-View-ViewModel](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel)) is the base pattern on which NativeScript framework is built. It facilitates the separation of development of the graphical user interface( XML code) from development of the business logic( Javascript or Typescript code).
+
+- **Model:** The model defines and represents the data. Separating the model from the various views that might use it allows for code reuse, better code maintainance and better testing.
+- **View:** The view represents the UI( [Button](/ui/components.md#button), [Page](/ui/components.md#page), [Label](/ui/components.md#label), etc), which in NativeScript is written in XML. The view is often data-bound to the view model so that changes made to the properties in the view model instantly trigger visual changes to UI components.
+- **View Model:** The view model contains the application business logic (often including the model, and exposes the data to the view. The `Observable` facilitates creating a view model object that can be bound to the view.
+ The biggest benefit of separating models, views, and view models, is that you are able to use two-way data binding; that is, changes to data in the model get instantly reflected on the view, and vice versa. The other big benefit is code reuse, as you're often able to reuse models and view models across views.
+
+The biggest benefit of separating models, views, and view models, is that you are able to use two-way data binding; that is, changes to data in the model get instantly reflected on the view, and vice versa. The other big benefit is code reuse, as you're often able to reuse models and view models across views.
+
+### MVVM example
+
+By default, when you create a new Nativescript app with the `ns create appName` command, you get an app project already arranged using the MVVM pattern. For example:
+
+
diff --git a/architecture-concepts/navigation.md b/architecture-concepts/navigation.md
new file mode 100755
index 00000000..867f5d2f
--- /dev/null
+++ b/architecture-concepts/navigation.md
@@ -0,0 +1,455 @@
+---
+title: Navigation
+---
+
+## Navigation
+
+Navigation refers to the act of moving around the screens of your application. Each mobile app has its own unique navigation schema based on the information it tries to present. The schema below is an example of a common mobile navigation scenario.
+![schema]()
+
+Based on the schema, there are three distinct navigational directions a user can move in:
+
+- **Forward** - refers to navigating to a screen on the next level in the hierarchy.
+- **Backward** - refers to navigating back to a screen either on the previous level in the hierarchy or chronologically.
+- **Lateral** - refers to navigating between screens on the same level in the hierarchy.
+
+This article demonstrates how you can implement these in NativeScript and combine them to build the navigation architecture of your application.
+
+## Forward Navigation
+
+![Forward navigation schema](/assets/images/architecture_concepts/navigation-schema-forward.png)
+
+Forward navigation can be also called **downward** navigation since you are going down in your navigation hierarchy. There are two navigation components in NativeScript that enable implementing forward navigation - [Frame](/ui/components.md#frame) and [Page](/ui/components.md#page). A Frame represents a navigation controller that navigates through Page instances.
+
+![Forward navigation schema](/assets/images/architecture_concepts/navigation-diagram-forward.png)
+
+### Page
+
+The Page is NativeScript's most basic navigation component. It represents a screen that the user can navigate to. This component serves two important roles. It holds the UI components of a single screen and provides navigation lifecycle events.
+
+By design, a Page can't be declared as a child of another component. It is used as a root component of a module, in which case the module becomes a page module. Here is an example of how you can implement the item-page module from the diagram above:
+
+
+
+```xml
+
+
+
+
+
+
+
+```
+
+
+
+```js
+export function onPageLoaded(args) {
+ console.log('Page Loaded')
+}
+```
+
+
+
+```ts
+import { EventData } from '@nativescript/core'
+
+export function onPageLoaded(args: EventData): void {
+ console.log('Page Loaded')
+}
+```
+
+### Frame
+
+To display a Page on the screen, you need to navigate to it using the Frame component. This component is the main provider of forward and backward navigation in NativeScript. The Frame component has no visible representation. It simply provides a container for transitions between pages. It also provides a navigation API which includes history manipulation and setting custom navigation transitions.
+
+For the most basic forward navigation scenario, you need only these two features:
+
+- `defaultPage` attribute - use this attribute to declare the initial page module that is displayed.
+- `navigate()` method - use this method to force a navigation to another page module.
+
+The following example demonstrates the implementation of the rest of the forward navigation diagram above. There is a Frame declared as root component in the app-root module. Upon load, the `Frame` will automatically navigate to the `featured-page` module. The `featured-page` module in turn has a button that navigates to the `item-page` module.
+
+
+
+```xml
+
+```
+
+
+
+```xml
+
+
+
+
+
+
+
+```
+
+
+
+```js
+export function onTap(args) {
+ const button = args.object
+ const page = button.page
+ page.frame.navigate('item-page')
+}
+```
+
+
+
+```ts
+import { EventData, Button, Page } from '@nativescript/core'
+
+export function onTap(args: EventData) {
+ const button: Button =