Pull to refresh

Native Script. Один код для всех платформ

Reading time4 min
Views60K
image

Native script (NS) – это библиотека, позволяющая делать кросс-платформенные приложения, используя XML, CSS, JavaScript. Native script решает ту же задачу, что и уже всем известный phonegap (создание кросс-платформенных приложений), но подходы у них разные. Phonegap использует движок браузера, чтобы отобразить ваш UI (фактически вы получаете веб-страницу), Native script использует нативный рендеринг, использует элементы нативного UI. Следующее важное отличие: чтобы получить доступ к камере, gps и так далее в phonegap необходимо устанавливать плагины, в то время как NS дает доступ из коробки.
Стоит подчеркнуть, что приложения можно писать для Android 4.2 и выше, и для iOS 7.1 и выше.

Быстрый старт


Чтобы установить native script, необходим nodejs, поэтому если у вас еще нет его, отправляйтесь сюда. Дальше все просто. Для установки NS в командной строке выполняем:

npm install -g nativescript

Для создания проекта:

tns create MyApp

После того, как проект создался, переходим в директорию проекта:

cd MyApp

И, как и в phonegap, добавляем платформы:

tns platform add android
tns platform add ios

Все готово, чтобы запустить наше первое native script приложение. Для того чтобы сделать это, нужно вести одну из следующих команд:

Запустить на устройстве, подключенном через USB:

tns run android 

Запустить в эмуляторе:

tns run android --emulator

Можно также запустить в Genymotion:

tns run android --geny <device name>

В общем, как бы вы не запускали, у вас откроется приложение, которое подсчитывает количество нажатий на кнопку, оставшихся до вывода текста «Hoorraaay! You unlocked the NativeScript clicker achievement!».



Вот сравнение как выглядит приложение на iOS и Android.



Как можно заметить, кнопка везде нативная, хотя код для обоих платформ один и тот же.

Что там внутри?


Структура проекта представлена ниже:



Все, что касается вида приложения, лежит в файле main-page.xml. Всех, кто привык работать с html, ужаснет этот файл, но благо документация очень хорошая, и чуть позже все становится понятнее.

<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded">
  <StackLayout>
    <Label text="Tap the button" cssClass="title"/>
    <Button text="TAP" tap="{{ tapAction }}" />
    <Label text="{{ message }}" cssClass="message" textWrap="true"/>
  </StackLayout>
</Page>

app.js – точка входа в приложение. В NS используются модули, так же как и nodejs. Думаю, тут все итак понятно.

var application = require("application");
application.mainModule = "main-page";
application.cssFile = "./app.css";
application.start();

main-page.js – содержит код для main-page.xml.

var vmModule = require("./main-view-model");
function pageLoaded(args) {
    var page = args.object;
    page.bindingContext = vmModule.mainViewModel;
}
exports.pageLoaded = pageLoaded;

Функция pageLoaded будет выполнена, в момент загрузки страницы (см. main-page.xml). Строка page.bindingContext = vmModule.mainViewModel устанавливает binding контекст для данной страницы (что-то наподобие $scope в ангуляр). Ну и последняя строка экспортирует функцию.

Следующий файл, main-view-model.js, позволит подробнее рассмотреть механизм data binding в NS. NS поддерживает two-way и one-way binding.

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var observable = require("data/observable");
var HelloWorldModel = (function (_super) {
    __extends(HelloWorldModel, _super);
    function HelloWorldModel() {
        _super.call(this);
        this.counter = 42;
        this.set("message", this.counter + " taps left");
    }
    HelloWorldModel.prototype.tapAction = function () {
        this.counter--;
        if (this.counter <= 0) {
            this.set("message", "Hoorraaay! You unlocked the NativeScript clicker achievement!");
        }
        else {
            this.set("message", this.counter + " taps left");
        }
    };
    return HelloWorldModel;
})(observable.Observable);
exports.HelloWorldModel = HelloWorldModel;
exports.mainViewModel = new HelloWorldModel();

Чтобы dataBinding работал, в NS объект должен выбрасывать событие propertyChange. Это реализовано в классе Observable. В нашем случае он передается в функцию, в которой HelloWorldModel наследует его. Дальше уже через метод set полям присваиваются значения. Функция __extends в самом верху файла служит для осуществления наследования.

Проверим двухсторонний binding в деле. Добавим в main-page.xml две строчки перед тегом .

<TextField text="{{ name }}" hint="введите ваше имя"/>
<Label cssClass="{{name, !!name ? 'title ' : 'title  hidden'}}" text="{{ name, 'Hello ' + name }}"/>  

В файле main-view-model.js в функцию HelloWorldModel добавим строку:

this.set("name", "");

И наконец в app.css. Стоит подчеркнуть, что поддерживаются далеко не все CSS свойства, полный список можно найти тут.

.hidden {
    visibility: collapsed;
}

В итоге получим:



Заключение


Native script для меня, как для веб-разработчика, оставил смешанные чувства. С одной стороны, видно, что авторы старались сделать все близко к вебу (JavaScript, CSS), но с другой, CSS свойства поддерживаются не все, чтобы разобраться с XML приходится постоянно лезть в документацию. Возможно NS решит проблемы, которые есть в phonegap, где то тут, то там появляются какие-то сложности, связанные с веб происхождением приложения. В любом случае, это круто, что появился еще один фреймворк, позволяющим знающим JavaScript писать кросс-платформенные приложения, т.к. на этом рынке становится тесно (phoneGap, Native Script, React Native) и как следствие качество фреймворков должно улучшаться.
Tags:
Hubs:
Total votes 29: ↑27 and ↓2+25
Comments23

Articles