Introdução ao NativeScript
O que é NativeScript?
O NativeScript é como você cria aplicativos iOS e Android multi-plataforma, nativos sem visualizações da web. Use Angular, TypeScript ou JavaScript puro para obter verdadeiramente UI nativa e desempenho enquanto compartilha habilidades e código com a web. Obtenha 100% de acesso a API nativas via JavaScript e reutilize pacotes de NPM, CocoaPods e Gradle.
O que não é NativeScript?
- Não é Cordova (Webview, DOM)
- Não é um compilador Cross
Exemplo Android
let time = new android.text.format.Time()
time.set(1, 0, 2015)
console.log(time.format("%D"))
O Resultado será:
"01/01/2015"
Exemplo IOS
let alert = new UIAlertView()
alert.message = "Hello World!"
alert.addButtonWithTitle("Ok")
alert.show()
E o resultado é:
Mas como é que isso funciona?
NativeScript e JS VMs
- NativeScript executa JavaScript com o JavaScript VM (Virtual Machine)
- JavaScriptCore no IOS
- V8 no Android
Sendo executado com V8
let time = new android.text.format.Time()
time.set(1, 0, 2015)
console.log(time.format("%D"))
Sendo executado com JavascriptCore
let alert = new UIAlertView()
alert.message = "Hello World!"
alert.addButtonWithTitle("Ok")
alert.show()
Utilizando as API's Nativas
- NativeScript usa reflexão para construir uma lista de APIs disponíveis para cada plataforma.
- Para um ótimo desempenho, este metadata é gerado previamente, e injetado no pacote do aplicativo em tempo de construção
Injetando API Nativa
- V8/JavascriptCore tem API's para injetar nas variaveis globais
Invocando API's
let time = new android.text.format.Time()
- V8 / JavaScriptCore tem retorno de chamada C++ para a função JS chamadas e acessos de propriedade.
- O tempo de execução do NativeScript usa esses callbacks para traduzir as chamadas JS para chamadas nativas.
- No iOS, você pode chamar diretamente as APIs Objective-C do C++.
- No Android, o NativeScript usa o JNI do Android (Java Interface Nativa) para fazer a ponte de C ++ para Java.
let time = new android.text.format.Time()
- (1) O retorno de chamada da função V8 é executado.
- (2) O tempo de execução do NativeScript usa seus metadados para saber que
Time()
significa que precisa instanciar um Objetoandroid.text.format.Time
. - (3) O tempo de execução do NativeScript usa o JNI para instanciar um objeto
android.text.format.Time
e mantém uma referência a ele. - (4) O tempo de execução do NativeScript retorna um objeto JS que proxy o objeto JavaTime.
- (5) Controle retorna para JS onde o objeto proxy é armazenado como uma variável de tempo local.
let time = new android.text.format.Time()
time.set(1, 0, 2015)
console.log(time.format("%D"))
Então você escreve apenas codigo nativo? NÃO
TNS Modules
- Módulos fornecidos com NativeScript que oferecem funcionalidade crossplatform.
- Há dezenas deles e são fáceis de escrever você mesmo.
- Os módulos TNS seguem as convenções do node module (CommonJS).
TNS File Module
const fileSystemModule = require("file-system")
new fileSystemModule.File(path)
Basicamente isso, se tornara os trechos a seguir...
// ANDROID
new java.io.File(path)
// IOS
NSFileManager.defaultManager()
fileManager.createFileAtPathContentsAttributes(path)
Modulo HTTP
const http = require('http')
http.getJSON("https://api.meuservico.com")
.then(response => {
// Resultado
})
Custom Modulos TNS
// device.ios.js
module.exports = {
version: UIDevice.currentDevice().systemVersion
}
// device.android.js
module.exports = {
version: android.os.Build.VERSION.RELEASE
}
Usando o Custom Modulo
const device = require('./device')
console.log(device.version)
Como inicio meu projeto?
- (1) Instalar NativeScript globalmente
npm install -g nativescript
- (2) Requesitos NativeScript CLI
- JDK, Apache Ant, Android SDK
- Xcode, Xcode CLI Tools, iOS SDK
Iniciando um novo Projeto
Depois que já instalou o NativeScript
tns create hello-world && cd hello-world
Executando no iOS
tns platform add ios && tns run ios --emulator
Executando no Android
tns platform add android && tns run android --emulator
Listagem de arquivos
- Hello-World (Pasta do seu projeto)
- app
- app.css <-- Estilo do app
- app.js <-- Ponto de inicialização
- main-page.css
- main-page.xml
- main-page.js
- node_modules <-- Modulos Node
- ...
- App_Resources <-- Icones, SplashScreen, Arquivos de configuração e etc
- ...
- Tns_Modules <-- Modulos do NativeScript
- ...
- platforms
- android
- ios
App.js
const application = require('application')
application.mainModule = 'main-page'
application.start()
Pages
- Estruturas XML
- Elementos (e.g.
<page>
,<Label>
)
<Page>
<Label text="Olá Pessoal ;)" />
</Page>
Data Binding
<Page loaded="load">
<Label text="Olá Pessoal ;)" />
</Page>
exports.load = (args) => {
args.object.bindingContext = {message: "Hello World!"}
}
Data Binding Melhorado
const observableModule = require('data/observable')
exports.load = (args) => {
let data = new observableModule.Observable()
data.set("message", "Hello World")
args.object.bindingContext = data
}
CSS
Label{
color: red;
font-size: 20;
width: 200;
margin: 20;
}
SURPREENDENTE, NÃO?