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) и как следствие качество фреймворков должно улучшаться.

Комментарии (19)


  1. hell0w0rd
    28.04.2015 11:23

    Они перестали при установке bashrc ломать?


  1. forceLain
    28.04.2015 11:40
    +4

    Еще один Titanium?


    1. forgotten
      29.04.2015 08:58

      Скорее, React Native


  1. iago
    28.04.2015 11:44
    +15

    Ну вот, пока приложения ограничиваются сложностью из примеров (Hello world и т.п.) — все работает отлично. Как только начинаются настоящие приложения — все летит к черту в том же Phonegap, Titanium и иже с ними, проверено сотни раз, уже сколько людей обломалось и вынуждено было платить повторно за нативную разработку.

    Даже в iOS, самой адекватной платформе, нативным кодом не так просто сделать некоторые вещи — что уж говорить про оболочки. Да даже свифт родной глючит страшно. Когда уже перестанут двигать эту ерунду? Десктопные платформы существуют сколько десятков лет, и то пообщавшись с разработчиками под QT удивляешься сколько еще нерешенных проблем.


    1. Ilusha
      28.04.2015 14:05

      Никто не говорит, что это волшебная пилюля. Что это кнопка «Сделать все хорошо».
      И никто не отрицает, что комбайн будет решать узко специализированную задачу хуже чем профильный инструмент. (Особенно, когда профильный не всегда корректно работает).
      Поэтому не понимаю такую критику.

      Предложен инструмент, который подходит для определенного класса задач, на вскидку:

      • черновой прототип;
      • простое приложение для собственных нужд или нужд узкого круга людей (семья, друзья и т.п.), к примеру для «умного» дома;
      • приложения, которым этого функционала реально достаточно.


      Не устраивает — не пользуйся.


      1. iago
        28.04.2015 16:47
        +3

        Я-то наемный рабочий, всегда найду где нужно писать нативно, но я вам приведу пример вреда от таких фрэймворков. Заказчики тоже читают такие новости и, не являясь разработчиками, ведутся на всю эту маркетинговую шелуху. Вы не представляете, сколько десятков раз людям придется убеждать заказчиков, что это тупиковый путь и сэкономить не получится. И это вместо того, чтобы делать клевые вещи. Отвечу также на ваши пункты:

        • в нативной разработке прототип обычно делается под первую платформу, например iOS, и делается черновыми средствами типа простейших контролов и сторибордов. Этого всегда хватает заказчику, чтобы пощупать функционал
        • простое приложение для умного дома обычно делается под одну платформу, и это обычно андроид, т.к. даже обеспеченные люди предпочитают ставить себе везде китайские планшеты за $100.
        • приложениям, для которых достаточно этого функционала, имхо, не место на маркете и в апсторе. Глубоко надеюсь, что эра фонариков и RSS-ридеров прошла в 2010-м.

        Извините, если резко что-то написал — я злюсь не на вас, а на маркетологов и несведущих людей. Даже сегодня, занимаясь продуктовой разработкой, я часто слышу на кухне от тех же JS разработчиков — «ну все, хана вашему iOS, скоро придет NativeScript и вы станете не нужны». За последние 6 лет мне эти утверждения уже ужасно набили оскомину.


        1. hell0w0rd
          28.04.2015 18:20

          На самом деле мне кажется вы не совсем правы. Конец IOS разработчикам естественно не прийдет, но под React Native, допустим, достаточно качественных биндингов. Вещи, которые не получается сделать существующими средствами отправляются IOS разработчику, для создания биндингов и все.
          А про заказчиков — это не грамотные заказчики, и такие есть в любой области, в том же вебе иногда требуется объяснить, что новомодный фреймворк/cms будет скорее мешать.
          В любом проекте правильно остановиться и задуматься, какой набор технологий подходит именно здесь и сейчас, как заказчику, так и разработчику.
          Примеры качественных приложений на JS вы, думаю, и так знаете. У facebook, судя по презентации приложения для фото и чата сделанны на React Native. Не помню какие именно, помню, что 2, и что они уже 2 года сущствуют.


          1. aylarov
            28.04.2015 21:42

            Под React Native пока мало всего и его нет под Android, но это вопрос времени. На мой вкус именно React Native наиболее перспективный фреймворк.


        1. Ilusha
          30.04.2015 21:17

          Я понимаю вашу мысль, и согласен с доводами.

          Но я всё равно за такие попытки сделать какую-нибудь библиотеку/фреймворк, который позволит использовать один код для ряда платформ. Да — с какими-то ограничениями и костылями, да — с проблемами.

          Я сам js-разработчик и мне хочется попробовать что-то сделать на мобильных устройствах, но изучение стека технологий для мобильных платформ будет для меня огромной потерей времени.


          1. iago
            04.05.2015 18:05

            Да ладно, я думаю вы сможете писать под iOS через неделю так же, как я на JS. Плохо, но для «попробовать что-то сделать» вполне приемлемо. У нас на самом деле нет такого стека, как у вас — у нас все гораздо проще.


          1. Woit
            05.05.2015 14:30
            +1

            Тогда вам, как js-разработчику пример из вашей предметной области: Поставлена задача, накропать простенький портал для организации средней руки. Вот только проблема, руководитель компании прочитал на хабре (еще б-г знает сколько лет назад), что есть такая замечательная штука как ASP.NET WebFroms (ни тебе Razor'а, ни тебе MVC, вообще ничего). Вы тщетно пытаетесь объяснить заказчику, что есть более простые/легкие/мощные средства из js-мира для реализации этой задумки и ASP.NET нинужна.

            Смысл нативных инструментов в том, что они предоставляют покрытие вообще всего функционала, который есть на устройстве. Пока речь идет о нативных кнопочках-окошечках все ок, как только разговор заходит о, например, гироскопе или нативной карте, то все, кроссплатформенные решение награждают вас адским адом.

            iago прав всецело и полностью: б-г с ними, с кроссплатформенными решениями, раз это кому-то интересно, то пусть живут. Но пожалуйста, не давайте читать это заказчикам.


    1. zapolnoch
      28.04.2015 18:06
      +1

      Расскажите, пожалуйста, в каком настоящем приложении у вас все полетело к черту? Спрашиваю без сарказма, реально интересно.


      1. iago
        29.04.2015 15:44

        На моей памяти было:
        — фитнес приложения у одной компании, писались на фрэймворке, работающем поверх Cocos2D — что-то вроде шагомеров и т.п. После года мучений решили все переписать и проклинают это время;
        — детское приложение писали (и пишут наверное) на чем-то поверх флекса. На iOS идет еще более-менее (хотя выглядит не нативно), на андроиде просто жуть.
        — мобильный банк на PhoneGap.
        — социалка типа 4square;

        Это так, навскидку. Не всё у меня конечно, привел примеры которые я знаю из первых рук. Как видите, обычные приложения, без 3д графики и особых требований к ресурсам — и даже они пролетают. Про что-то сложнее, например как мы писали для форекса, даже говорить не приходится — будет картинка слайд-шоу.


        1. Aracon
          29.04.2015 18:04

          То есть основная проблема в производительности? Или в чем?


          1. iago
            30.04.2015 17:25

            Да во всем. Производительность — в первую очередь, потом идет кроссплатформенность. Т.е. то, из-за чего собственно все и затеивалось, работает из рук вон плохо.


        1. Blumfontein
          29.04.2015 18:48

          >> на андроиде просто жуть.

          У Андроидов < 4.4 жутко кривой WebView, начиная с 4.4 по дефолту идет Chrome WebView, и все работает получше. Проблема ненативных средств разработки не в самих этих средствах, а в кривых эмуляторах жаваскрипта.


  1. comerc
    28.04.2015 11:55

    Интересно, если подружить с Метеором.


  1. snegovikufa
    29.04.2015 08:53
    +1

    Делал на нем приложение. Очень сильно тормозит при запуске на платформе Art, так что не юзабельно


    1. IamKarlson
      07.05.2015 15:55
      +1

      Да ладно там на запуске. Вообще весь процесс какой-то адово кривой. Эмулятор работает через раз, ошибки возвращают вообще не дебаживаемые, надо лезть в исходники и смотреть почему ж там, %!@#$, не запустилось. Хоть мне и понравилось на ноде писать, но отдебажить эту ошибку стоило н-ного количества месаджбоксов. Причем процесс компиляции очень долгий сам по себе, обещали к 1 версии исправить, но я плюнул и не стал дальше его мучить. Инструментов тоже никаких толком нет под него. А то что есть, телерик просит занести н-ную сумму денег к ним в кассу. При условии что все остальные «кроссплатформенные» обладают тем же набором детских болезней, не лучше уж взять Titanium, у которого хоть IDE есть (Appcelerator Studio IDE)? Или Xamarin (у них бесплатные контролы для платформ?)?