StormSnapshot

React Native vs Ionic

Ionic vs React Native -> StormSnapshot #5

Jako podsumowanie artykułów wprowadzających do React Native oraz Ionic przygotowałem zbiorcze porównanie tych technologii. Pomoże mi to podjąć decyzję, która z nich lepiej będzie nadawała się do projektu StormSnapshot.

Wybór nie jest łatwy, ponieważ oba rozwiązania spisały się bardzo dobrze i z powodzeniem można by je wykorzystać do dalszego rozwijania projektu.

Żeby decyzja była bardziej wiarygodna, wróćmy na chwilę do tekstu: mobilne aplikacje hybrydowe i prześledźmy kolejno zebrane wtedy wymagania.

Stos technologiczny

  • Ionic: Angular, Apache Cordova, HTML, JavaScript, CSS
  • React Native: React, HTML, JavaScript

Oba frameworki wykorzystują bardzo popularne i sprawdzone technologie. To, które rozwiązanie wybrać, to raczej kwestia indywidualnych preferencji oraz posiadanych już umiejętności.

Na korzyść pierwszego przemawia prostota stylowania, za sprawą wykorzystania istniejących standardów webowych. Natomiast dzięki Reactovi otrzymujemy w pełni natywną aplikację.

W tym starciu nie ma jednoznacznego zwycięzcy.

Wydajność aplikacji

Ponieważ Ionic wykorzystuje wbudowaną przeglądarkę, a React Native generuje natywną aplikację, spodziewałem się dość wyraźnych różnic w prędkości działania wynikowego produktu.

Sam moment uruchomienia aplikacji w przypadku natywnej aplikacji jest znacząco krótszy. Na testowanym telefonie (LG G3) była to aż ponad dwukrotna różnica (2 s. natywna i 5 s. webview).

Jednak już podczas samego działania aplikacji obu technologiom nie miałem nic do zarzucenia. W obu przypadkach aplikacja chodziła płynnie i nie przycinała się.

W tym starciu jednak wygrywa React Native.

Szybkość i prostota developmentu

Obie technologie wychodzą z całkowicie innych założeń.

  • W przypadku Ionic z założenia piszemy jedną aplikację, która będzie działała na wszystkich obsługiwanych systemach.
  • W przypadku React Native dostajemy technologię, przy pomocy której możemy pisać aplikacje na różne systemy. Dzięki jednej spójnej technologii znaczna część kodu może być współdzielona.

Podejście React Native wymaga trochę więcej wysiłku, jednak pozwala lepiej dopasować aplikacje do specyficznych funkcjonalności na danej platformie.

Ponieważ frameworki realizują to wymaganie w całkowicie inny sposób, nie można ich w prosty sposób porównać.

Prostota debugowania i testowania aplikacji

  • Ionic: Bezproblemowe i bardzo szybkie debugowanie zmian z poziomu przeglądarki. W moim odczuciu ogromny plus za możliwość edytowania wyglądu aplikacji w locie.
  • React Native: Ponieważ kod aplikacji jest kompilowany do natywnej wersji, testowanie zmian jest trochę utrudnione. Jednak dzięki zastosowaniu hotdeployu komponentów, nie stanowi to aż tak dużego problemu.

W tym starciu nieznacznie wygrywa Ionic.

Możliwość dopisania własnych komponentów

Oba rozwiązania dają możliwość dopisania własnych niestandardowych pluginów. Nie testowałem jednak tego w przykładowych aplikacjach.

Społeczność

W obu przypadkach za projektem stoi bardzo silna i dynamiczna społeczność. Baza dostępnych pluginów jest tak duża, że z powodzeniem można w niej znaleźć większość potrzebnych dodatków.

Dla obu stron ogromny plus.

Ogólne odczucia

Mimo iż z obu technologii korzystało mi się dobrze, React Native sprawiał wrażenie rozwiązania dużo bardziej dopracowanego. Poczynając od samej instalacji, do developmentu i debugowania aplikacji, odniosłem wrażenie, że w technologi od Facebooka wszystko jest dobrze dopieszczone i działa tak, jak powinno.

Podsumowanie React JS vs Ionic: który wybrać?

Niewątpliwie obie technologie stoją na bardzo wysokim poziomie i z czystym sumieniem mogę polecić obie.

Rozwiązania wykorzystują całkowicie inne założenia i inne technologie, dlatego mogą lepiej sprawdzić się w różnych projektów. W moim przypadku decyduję się na dalsze rozwijanie projektu StormSnapshot z wykorzystaniem React Native.

Linki

No comments
Share:
Ionic pierwsza aplikacja

Ionic pierwsza aplikacja -> StormSnapshot #4

Ostatecznie, po dość nierównej walce (więcej na ten temat możesz przeczytać we wpisie: CO ROBIĆ, gdy nic nie działa i wszystko się wali!?) zapraszam do lektury artykułu o Ionic Framework.

Podobnie jak we wcześniejszym tekście o React Native zamierzam przeprowadzić Cię krok po kroku przez przygotowanie niezbędnego środowiska oraz development przykładowej aplikacji, demonstrującej możliwości biblioteki.

Ionic

Ionic to kompletne SDK do wytwarzania mobilnych aplikacji hybrydowych. Biblioteka zbudowana jest z wykorzystaniem znanych technologii, takich jak: AngularJS oraz Apache Cordova.

Mimo iż aplikacje pisane są z wykorzystaniem HTML, JavaScript i CSS, to jako mobilne aplikacje hybrydowe mogą być dystrybuowane jak każda inna aplikacja natywna.

Ionic vs PhoneGap

No dobrze, ale skoro Ionic wykorzystuje PhoneGap, to czemu nie korzystać z samego PhoneGap?

Decydując się na Ionic, dostajemy nie tylko narzędzie do budowania aplikacji hybrydowych, ale również gotowe biblioteki JavaScript i cały zbiór stylów definiujących ostateczny wygląd.

Sprawia to, że powstały produkt wyglądem jest bardziej zbliżony do aplikacji natywnych, a my nie musimy zaczynać projektu całkowicie od zera. Chcąc osiągnąć podobny efekt korzystając tylko z Apache Cordova, na starcie trzeba by włożyć sporo więcej pracy.

Instalacja Ionic

Do instalacji niezbędnych komponentów skorzystamy z menagera pakietów npm, który zainstalowaliśmy już przy konfiguracji środowiska dla React Native.

Przy jego pomocy instalujemy pakiety Cordova i Ionic:

npm install -g cordova ionic

Warto również sprawdzić, czy nodejs oraz npm są aktualne. Niestety niezgodność wersji może powodować dość dziwne błędy. Ja doinstalowałem również pakiety: reflect-metadataangular-cli.

Całe proces instalacji można prześledzić w dokumentacji: Installing Ionic and its Dependencies.

Pierwszy projekt Ionic

Przy pomocy wiersza poleceń generujemy strukturę przykładowej aplikacji.

sudo ionic start IonicSampleProject tabs --v2

Na ten moment domyślnie generowany jest projekt w wersji Ionic 1 dlatego, żeby wymusić korzystanie z wersji 2 koniecznie jest dodanie argumentu: –v2.

Aplikacja generowana jest na podstawie predefiniowanych szablonów. Domyślnie mamy do wyboru: tabs, sidemenu oraz blank.

Więcej o szablonach oraz samym generowaniu projektu przeczytasz w rozdziale: Starting an Ionic App.

Struktura projektu Ionic

Struktura projektu jest zbliżona do czystego projektu Apache Cordova. Projekt poza głównym plikiem config.xml zawiera również pliki konfiguracyjne specyficzne dla Ionic.

Ionic struktura projektu

Ionic struktura projektu

./src/index.html

Plik index.html to główny punkt wejścia do aplikacji. Z jego poziomu załączone są wszystkie pliki niezbędne do działania kodu z PhoneGap oraz uruchamiany jest główny komponent Ionic, ładujący całą aplikację:

<ion-app></ion-app>

Uruchomienie i testowanie aplikacji Ionic

Ponieważ aplikacja jest specyficzną stroną www, można ją uruchomić w zwykłej przeglądarce internetowej.

W tym celu skorzystamy z wbudowanego serwera. Z poziomu katalogu projektu uruchamiamy poniższą komendę:

ionic serve

W zależności od wybranego wcześniej szablonu, w przeglądarce możemy zobaczyć np. taki widok.

Ionic pierwsza aplikacja

Ionic pierwsza aplikacja

Uruchomienie aplikacji na emulatorze i urządzeniu fizycznym

Przed uruchomieniem aplikacji na konkretnej platformie, musimy najpierw dodać ją do projektu.

ionic platform add android

Po tym kroku projekt można już spokojnie zbudować i przetestować jego działanie na emulatorze lub na fizycznym urządzeniu.

ionic run android
Ionic emulator

Ionic emulator

Aplikacja

Aplikacja realizująca zbliżone funkcjonalności do tej napisanej w React Native. Dla przypomnienia: mamy 3 widoki:

  • ekran powitalny;
  • lista przechowująca wiele elementów;
  • lista generowana na podstawie kanału RSS;

Nawigacja w aplikacji

Ponieważ skorzystałem z szablonu tabs, znaczna część pracy była już gotowa.

Ionic zakładki

Ionic zakładki

Całość logiki aplikacji podzielona jest na strony, które są przechowywane w katalogu: src/pages.

Przejściami między poszczególnymi stronami zarządza sekcja tabs, a tag <ion-tabs /> generuje menu widoczne w dole aplikacji.

Kod każdej ze stron podzielony jest na 3 pliki:

  • *.html
    szablon zawierający tagi Ionic i HTML
  • *.scss
    style Sass
  • *.ts
    plik TypeScript zawierający właściwą logikę

Stylowanie [Sass – syntactically awesome stylesheets]

Stylowanie aplikacji niewiele różni się od pracy ze zwykłą stroną. Do dyspozycji mamy rozszerzoną składnię Sass, co w praktyce sprawia, że osoba znająca przynajmniej podstawy CSS nie powinna mieć najmniejszych problemów z tym zadaniem.

Poszczególne pliki SCSS są kompilowane i dołączane w wynikowej formie do aplikacji.

Jest to ogromny plus tej technologii. Wygląd można edytować w czasie rzeczywistym, np. korzystając z Google Chrome Developer Tools i dopiero po uzyskaniu zamierzonego efektu nanieść zmiany na kod aplikacji.

Lista danych

Ionic lista danych

Ionic lista danych

Listę danych przygotowałem z wykorzystaniem komponentu ion-list. W tym celu w pliku z szablonem (list.html) dodajemy tag: ion-list oraz w pętli wyświetlamy wszystkie elementy tej listy.

<ion-content>
  <ion-list>
    <ion-list-header>List</ion-list-header>
    <ion-item *ngFor="let item of items">
      <h2>{{item.title}}</h2>
    </ion-item>
  </ion-list>
</ion-content>

Wykorzystaną w szablonie zmienną: items trzeba jeszcze zadeklarować w pliku komponentu (list.ts)

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-list',
  templateUrl: 'list.html'
})
export class ListPage {

  items : any;

  constructor(public navCtrl: NavController) {
      this.items = [];
      for(let i=0; i<100; i++){
        let item = {
            title: 'Row item numer : ' + i
          };
        this.items.push(item);
      }
  }
}

RSS – pobranie danych z Internetu

Do samego wyświetlenia danych, podobnie jak w przypadku zwykłej listy, wykorzystałem komponent: ion-list. W pliku szablonu deklarujemy tagi jak poprzednio i przechodzimy do pliku z TypeScript, żeby zasilić listę danymi.

constructor(public navCtrl: NavController, public http: Http) {
    this.http.get('https://stormit.pl/feed').map(res => res.text()).subscribe(data => {
        this.parseXML(data).then((data) => {
            this.items = data
        });
    });
}

Samo pobranie danych z Internetu jest stosunkowo proste. Korzystamy w tym celu ze standardowego komponentu Angulara: HTTP oraz metody map.

Obie metody trzeba jeszcze załączyć do naszego pliku poniższymi importami.

import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

Parsowanie XML [xml2js]

Do parsowania pobranego pliku XML skorzystamy z zewnętrznej biblioteki: xml2js.

Bibliotekę trzeba najpierw doinstalować, a potem dołączyć do projektu:

npm install xml2js
import xml2js from 'xml2js';

Następnie przy jej pomocy można napisać już właściwą metodę parsującą dane.

parseXML(data) {
    return new Promise(resolve => {
        var arr = [],
            parser = new xml2js.Parser({
                trim: true,
                explicitArray: true
            });

        parser.parseString(data, function(err, result) {
            for (let i in result.rss.channel[0].item) {
                var item = result.rss.channel[0].item[i];
                arr.push({
                    title: item.title[0]
                });
            }

            resolve(arr);
        });
    });
}

Ionic Proxy i No 'Access-Control-Allow-Origin’

Testując aplikację lokalnie, np. z wykorzystaniem ionic serve, można wygenerować błąd typu CORS. Ponieważ aplikacja jest uruchamiana w wewnętrznej przeglądarce (serwer localhost), w ramach bezpieczeństwa, żądania ajax do innych domen są blokowane.

XMLHttpRequest cannot load https://stormit.pl/feed. Redirect from 'https://stormit.pl/feed' to 'https://stormit.pl/feed/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.

Można to obejść na dwa sposoby:

  1.  Zmieniając ustawienia bezpieczeństwa np. przez dodanie na serwerze hostującym usługę odpowiedniego nagłówka http.
  2. Skorzystać z lokalnego serwera proxy.

Ja skorzystałem z proxy. Całe szczęście mamy do tego przygotowany już gotowy mechanizm.

Wystarczy zrobić dwie rzeczy:

  • w głównym pliku konfiguracyjnym: ionic.config.json dodać odpowiedni wpis mapujacy lokalny adres na zewnętrzną domenę;
  • oraz w kodzie aplikacji podmienić wszystkie wywołania na adres proxy, w tym wypadku będzie to: http://localhost:8100/rss.
"proxies": [
  {
    "path": "/rss",
    "proxyUrl": "https://stormit.pl/feed"
  }
]

Żeby co chwilę nie zmieniać adresów usługi, najlepiej przenieść je do stałych i ich wartość uzależnić od tego, czy aplikacja jest uruchamiana testowo, czy już produkcyjnie.

Obsługa błędów i debugowanie

Do debugowania można wykorzystać konsolę z Google Chrome, a sam framework udostępnia również fajne wsparcie do wyświetlania błędów z aplikacji.

Ionic błąd

Ionic błąd

Podsumowanie

Ionic już na samym starcie dość mocno mi dokuczył. Jednak dla mnie dużo większe znaczenie ma to, jak z danej technologii się korzysta, a nie to jak ją się instaluje.

Tutaj Ionic zdecydowanie nadrobił początkowe straty. Nie miałem najmniejszych problemów ze zrealizowaniem wszystkich zamierzonych funkcjonalności.

Sam proces developmentu jest dość prosty i przyjemny. Dużym plusem szczególnie na starcie jest możliwość edytowania szablonów i stylów bez konieczności nauki dodatkowych technologii.

Technologia świetnie się sprawdza szczególnie dla małych projektów, ponieważ dzięki wbudowanym szablonom lub korzystając z kreatora bardzo szybko można przygotować proste widoki i funkcjonalności.

Aplikacja na testowych danych działała płynnie i nie przycinała się. Nie odbiegała jakością działania od innych programów zainstalowanych na moim telefonie.

Linki

5 komentarzy
Share:
React Native pierwsza aplikacja

React Native pierwsza aplikacja -> StormSnapshot #3

Witam w kolejnej części serii StormSnapshot. W poprzednim wpisie mobilne aplikacje hybrydowe zebraliśmy podstawowe informacje o dostępnych technologiach oraz wybraliśmy dwa najlepiej rokujące frameworki: Ionic, oraz React native.

Dzisiaj przyjrzymy się bliżej technologii React Native i przygotujemy prostą aplikację testową.

React i React Native

React (nazywany również React.js lub ReactJS) to biblioteka JavaScript, rozwijana na licencji open source, do budowania interfejsu użytkownika. Projekt wspierany jest głównie przez ludzi z Facebooka i Instagrama.

Dzięki React Native można budować mobilne aplikacje, korzystając tylko z JavaScriptu. Powstała aplikacja nie jest typową aplikacją hybrydową wykorzystującą webview do prezentacji strony mobilnej, jak robi to np. PhoneGap. Zamiast tego na podstawie komponentów napisanych w składni React budowane są natywne komponenty w Javie na Androida, czy w Objective-C na iOS.

Motto React Native

Motto React Native

Większości frameworków hybrydowych przyświeca motto: „Write once, run anywhere” (napisz raz, uruchom wszędzie), jednak w przypadku Reacta zostało ono sparafrazowane na: „Learn once, write anywhere” (naucz się raz, pisz wszędzie).

„Write once, run anywhere”

Oddaje to dobrze ideę, która przyświeca temu projektowi. Zamiast pisać jeden kod, który będziemy mogli bez modyfikacji uruchomić na wszystkich dostępnych platformach, dostajemy jedno narzędzie, które możemy wykorzystać niezależnie czy piszemy stronę www, czy aplikację mobilną. Takie podejście teoretycznie wymaga trochę więcej wysiłku, ale pozwala uzyskać bardziej dopasowane aplikacje.

Learn once, write anywhere

W efekcie tego, migrując np. projekt z Androida na iOS, trzeba będzie pochylić się jedynie nad częścią komponentów, ale zdecydowana większość kodu może zostać wykorzystana jako część wspólna. Resztę kodu stanowią komponenty i funkcjonalności dostępne tylko na danym systemie operacyjnym.

Wprowadzenie do JSX

Komponenty dostępne w React pisane są zazwyczaj przy pomocy składni JSX. JSX to rozszerzenie składni JavaScript o możliwość prostego wykorzystywania tagów HTML. Użyte tagi są przetwarzane i zamieniane na odpowiednie wywołania biblioteki js.

const element = <h1>Hello, Java!</h1>;

Powyższy fragment kodu to prosta konstrukcja JSX. Składnia trochę przypomina sam widok HTML, przy jego pomocy można jednak w pełni korzystać z możliwości JavaScript.

Osadzenie wyrażeń w JSX

W JSX można wykorzystać dowolne wyrażenia JavaScript, osadzając je w nawiasach klamrowych:

function format(obj){
   return 'Hello '+obj.title.toUpperCase();
}
return (<Text>{format({title: 'jsx'})}</Text>);

IDE

Początkowo projekt chciałem realizować z wykorzystaniem Netbeans IDE. Niestety w obecnej wersji (8.2) Netbeans ma jeszcze bardzo słabe wsparcie dla składni JSX, nie znalazłem też żadnego pluginu spełniającego moje oczekiwania. Nie wyobrażam sobie pisania większego projektu w dowolnej technologii bez przynajmniej podstawowego wsparcia w podpowiadaniu składni.

Między innymi dlatego zdecydowałem się skorzystać z IntelliJ IDEA. Niestety IntelliJ ma wsparcie dla JavaScript i składni JSX tylko w pełnej płatnej wersji. Można jednak pobrać 30-dniową wersję próbną.

Pierwszy projekt

Przed rozpoczęciem pracy musimy przygotować środowisko programistyczne oraz wszystkie niezbędne narzędzia. Pierwsza wersja aplikacji będzie dostępna na Androida, natomiast system operacyjny, z którego korzystam to Linux Ubuntu.

Niezbędne narzędzia

Ponieważ aplikacja będzie dostępna na Androidzie, musimy zacząć od instalacji Android Studio.

React Native wykorzystuje Node.js jako silnik do budowania kodu JavaScript, dlatego potrzebujemy również jego.

sudo apt-get update
sudo apt-get install nodejs
sudo apt-get install npm

Kolejnym narzędziem, którego potrzebujemy, jest: React Native Command Line Interface (CLI):

sudo npm install -g react-native-cli

Więcej na temat niezbędnych narzędzi można przeczytać na React Native Getting Started.

Struktura projektu

Po instalacji wszystkich niezbędnych narzędzi możemy przejść do wygenerowania struktury przykładowego projektu. Przechodzimy do docelowego katalogu i poniższym poleceniem generujemy strukturę naszej aplikacji:

react-native init ReactNativeSampleProject

Wygenerowane pliki zawierają wszystko, co potrzeba do uruchomienia pierwszej aplikacji w React Native.

Projekt React Native

Projekt React Native

W katalogu głównym projektu znajduje się plik: index.android.js, który jest punktem wejścia dla aplikacji. W tym samym katalogu znajdziemy jeszcze katalog: node_modules zawierający pliki biblioteki React Native oraz katalog android z kodem specyficznym dla tej platformy.

Uruchomienie aplikacji na symulatorze i urządzeniu

Zaczynamy od uruchomienia serwera React Native, który będzie przechowywał pliki JavaScript. Przechodzimy do katalogu z wygenerowanym wcześniej projektem i odpalamy poniższą komendę:

sudo react-native start

W osobnej konsoli możemy już zbudować i uruchomić przygotowany projekt:

react-native run-android

Jeżeli wszystko poszło dobrze, program powinien zainstalować na dostępnym symulatorze oraz fizycznym urządzeniu nową aplikację.

React Native emulator

React Native emulator

Aplikacja

Nasza aplikacja ma jedno proste zadanie, mianowicie przetestowanie podstawowych możliwości React Native. W tym celu przygotujemy kilka widoków:

  • ekran powitalny
    Na tym widoku wyświetlimy logo oraz damy możliwość przejścia do pozostałych widoków.
  • lista
    Wyświetlenie przewijanej listy 100 elementów.
  • rss
    Pobranie z Internetu oraz wyświetlenie listy najnowszych postów z bloga. Poszczególne wpisy będą miały tytuł i obrazek.

Navigator – przejścia w aplikacji

Całą aplikację podzielimy na poszczególne widoki reprezentujące osobne funkcjonalności. Natomiast główny plik index.android.js będzie zawierał komponent Navigator odpowiedzialny za przejścia w aplikacji.

import React, {Component} from 'react';
import {AppRegistry, Navigator} from 'react-native';

import StartScreen from './screens/StartScreen';
import ListScreen from './screens/ListScreen';
import RssScreen from './screens/RssScreen';
import SettingsScreen from './screens/SettingsScreen';

class StartApp extends Component {
    renderScene(route, navigator) {
        if (route.name == 'StartScreen') {
            return <StartScreen navigator={navigator}/>
        }
        if (route.name == 'SettingsScreen') {
            return <SettingsScreen navigator={navigator}/>
        }
        if (route.name == 'ListScreen') {
            return <ListScreen navigator={navigator}/>
        }
        if (route.name == 'RssScreen') {
            return <RssScreen navigator={navigator}/>
        }
    }

    render() {
        return (
            <Navigator
                initialRoute={{name: 'StartScreen'}}
                renderScene={this.renderScene.bind(this)}
            />
        );
    }
}

AppRegistry.registerComponent('ReactNativeSampleProject', () => StartApp);

Początek kodu to import wszystkich potrzebnych komponentów z frameworka oraz zdefiniowanych przez nas widoków. Poszczególne widoki zebrałem dla porządku w katalogu screens.

W metodzie renderScene na podstawie przekazanej nazwy generujemy odpowiedni widok. Do wszystkich widoków przekazujemy obiekt navigatora, żeby również z nich można było robić przejścia.

import React, {Component} from 'react';

export default class Screen extends Component {
    redirect(routeName) {
        this.props.navigator.push({
            name: routeName
        });
    }

    back() {
        this.props.navigator.pop();
    }
}

Wszystkie widoki dziedziczą z tej samej klasy Screen, dzięki czemu można było wydzielić w jedno miejsce zarządzenie przejściami.

Menu aplikacji [TouchableHighlight]

ReactNativeSampleProject-startScreen

ReactNativeSampleProject-startScreen

Jako menu wykorzystałem obrazki oraz abstrakcyjny komponent TouchableHighlight przechwytujący kliknięcia. Po wybraniu konkretnego obrazka wywoływana jest metoda onPress, która zwraca przygotowaną metodę z przekierowaniem do nowego widoku.

export default class StartScreen extends Screen {
    render() {
        return (<View style={styles.container}>
            <Image style={styles.logo} source={require('../img/logo.png')}/>
            <Text style={styles.title}>ReactNativeSampleProject</Text>
            <View style={styles.images}>
                <TouchableHighlight onPress={this.redirect.bind(this, 'SettingsScreen')}>
                    <Image style={styles.image} source={require('../img/settings.png')}/>
                </TouchableHighlight>
                <TouchableHighlight onPress={this.redirect.bind(this, 'ListScreen')}>
                    <Image style={styles.image} source={require('../img/list.png')}/>
                </TouchableHighlight>
                <TouchableHighlight onPress={this.redirect.bind(this, 'RssScreen')}>
                    <Image style={styles.image} source={require('../img/rss.png')}/>
                </TouchableHighlight>
            </View>
        </View>);
    }
}

Stylowanie aplikacji [StyleSheet]

Stylowanie aplikacji w React Native przebiega podobnie jak w zwykłych kaskadowych stylach CSS. W wypadku wielu właściwości wystarczy zamienić argumenty z myślnikiem, jak background-color, na konwencję camelCase backgroundColor.

Style można definiować inline jednak zazwyczaj lepszym pomysłem jest wydzielenie ich z kodu do stałych.

const styles = StyleSheet.create({
    wrapper: {
        backgroundColor: '#3399ff',
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    },
    logo: {
        flex: 1,
        width: 150,
        height: 150,
        resizeMode: 'contain'
    },
    images: {
        flexDirection: 'row'
    },
    image: {
        margin: 10,
        width: 50,
        height: 50,
    },
    title: {
        color: 'white'
    }
});

To rozwiązanie może nie jest tak wygodne jak wykorzystanie samych styli CSS. Jednak nawet podstawowa znajomość CSS powinna wystarczyć do w miarę bezbolesnego wykorzystania tego podejścia.

Lista danych [ListView]

Ten widok ma na celu przetestowanie długiej listy rekordów dostępnej z komponentu ListView.

export default class ListScreen extends Screen {

    constructor(props) {
        super(props);
        this.prepareRows();
    }

    prepareRows() {
        const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1.title !== r2.title});
        const images = [
            require('../img/list.png'),
            require('../img/rss.png'),
            require('../img/settings.png')];
        let rows = [];
        for (let i = 0; i < 100; i++) {
            let image = images[i % images.length];
            rows.push({image: image, title: 'Row item number : ' + i});
        }
        this.state = {
            dataSource: ds.cloneWithRows(rows),
        };
    }

    render() {
        return (
            <View>
                <ListView
                    dataSource={this.state.dataSource}
                    renderRow={(rowData) => <View style={styles.row}>
                            <Image style={styles.image} source={rowData.image}/>
                            <Text>{rowData.title}</Text>
                        </View>}
                    renderFooter={() =>                 <View style={styles.back}>
                            <TouchableHighlight onPress={this.back.bind(this)}>
                                <Text>Wróć</Text>
                            </TouchableHighlight>
                        </View>}
                />
            </View>
        );
    }
}

Komponent ListView umożliwia proste operowanie na przewijanej liście rekordów. Wystarczy podać źródło danych oraz zdefiniować metodę renderRow, odpowiedzialną za wygenerowanie jednego wiersza listy.

RSS – pobranie danych z Internetu

ReactNativeSampleProject-rssScreen

ReactNativeSampleProject-rssScreen

Kolejny widok aplikacji to przykład pobrania danych z Internetu oraz parsowania XML-a. Na podstawie danych pobranych z sieci (kanał RSS) budowana jest lista z wykorzystaniem ListView.

fetchData() {
    fetch('https://stormit.pl/feed')
        .then((response) => response.text())
        .then((responseText) => {
            ...
        })
        .done();
}

Parsowanie XML

Do sparsowania pobranego pliku XML wykorzystałem zewnętrzny komponent DOMParser, który należy doinstalować do projektu poniższą komendą.

npm install react-native-html-parser

W podobny sposób można zainstalować inne komponenty. Pokaźna lista komponentów dostępna jest w katalogu.

var DOMParser = require('react-native-html-parser').DOMParser;
const domParser = new DOMParser();
const doc = domParser.parseFromString(responseText, 'text/xml');

let items = doc.getElementsByTagName('item');

let objs = []
for (var i = 0; i < items.length; i++) {
    const parsedDescription = domParser.parseFromString(items[i].getElementsByTagName('description')[0].textContent, "text/xml");
    objs.push({
        title: items[i].getElementsByTagName('title')[0].textContent,
        uri: items[i].getElementsByTagName('link')[0].textContent,
        image: this.getSmallestSrc(parsedDescription.getElementsByTagName('img')[0].getAttribute('srcset'))
    })
}

Podsumowanie

W moim odczuciu framework przeszedł bardzo dobrze ten test. Mimo iż jest to moja pierwsza styczność z tą technologią, nie miałem większych problemów z realizacją podstawowych funkcjonalności. Na stronie projektu można znaleźć bardzo pomocną dokumentację, która praktycznie krok po kroku wprowadza programistę w tajniki frameworka.

Powstała aplikacja działa płynnie i nie przycina się. Ciężko mieć tu jakieś zastrzeżenia, nawet przy dużej ilości danych.

Dopracowanie wyglądu samej aplikacji wymaga trochę wysiłku, ale bez większego trudu w sieci można znaleźć gotowe przykłady ostylowanych komponentów.

Podsumowując, z React Native korzysta się naprawdę dobrze, technologia stoi na wysokim poziomie, a powstała z jej pomocą aplikacja nie odbiega jakością od natywnych odpowiedników.

Jestem bardzo ciekaw, jak w tym porównaniu wyjdzie Ionic, ale już teraz widzę, że nie będzie miał łatwego zadania.

Linki

 

kierunek java

 

No comments
Share:
Mobilne aplikacje hybrydowe

Mobilne aplikacje hybrydowe -> StormSnapshot #2

To już trzecia część cyklu StormSnapshot. W poprzednim wpisie kurs aplikacji mobilnych zebraliśmy podstawowe różnice między aplikacjami hybrydowymi a natywnymi oraz przedstawiliśmy argumenty przemawiające za każdym z tych rozwiązań.

Dzisiaj zajmiemy się porównaniem najbardziej znanych frameworków mobilnych aplikacji hybrydowych.

Co jest dla mnie najważniejsze?

To zasadnicze pytanie z punktu widzenia tego porównania. Frameworków dla aplikacji mobilnych jest tak dużo, że musimy najpierw zastanowić się, na co zwrócić uwagę i jakie ich cechy są dla nas najważniejsze.

Stos technologiczny

Stos technologiczny, czyli to, z jakich technologi będziemy korzystać, jest niezwykle ważny. Już wcześniej powiedzieliśmy sobie, że nie chcemy pisać aplikacji natywnych, żeby nie skupiać się na technologiach typowo specyficznych dla danej platformy.

Z mojego punktu widzenia idealny stos technologiczny to połączenie Javy oraz technologii webowych: JavaScript, HTML i CSS.

Wydajność aplikacji

Powstała aplikacja będzie uruchamiana na urządzeniach mobilnych, czyli w środowisku o dość ograniczonych zasobach.

Wykorzystane technologie powinny zapewniać możliwie największą płynność działania aplikacji. Użytkownicy są bardzo niecierpliwi. To, że aplikacja przycina się lub zwyczajnie działa za wolno, w tym wypadku jest nie do zaakceptowania. Znaczenie ma również rozmiar powstałej aplikacji i ilość wykorzystywanej pamięci RAM, jednak nie jest to kluczowe.

Szybkość i prostota developmentu

Aplikację powinno pisać się prosto, szybko i przyjemnie 🙂 Na ten punkt składa się wiele czynników, jednak przede wszystkim: wykorzystane technologie, ilość i jakość dostępnych komponentów oraz możliwość szybkiego testowania wprowadzanych zmian w kodzie.

Prostota debugowania i testowania aplikacji

Nie ma chyba nic bardziej denerwującego dla programistów niż długie przebudowywanie aplikacji, żeby sprawdzić, czy dany przycisk będzie lepiej wyglądał dwa piksele w lewo, a może jeden w prawo…

Zmiany wprowadzane w aplikacji powinny być widoczne dla programisty możliwie jak najszybciej.

Możliwość dopisania własnych, niestandardowych komponentów

Żaden, nawet najlepszy, framework nie jest w stanie dostarczyć wszystkich funkcjonalności. Wykorzystane rozwiązanie powinno udostępniać możliwość napisania fragmentu kodu z wykorzystaniem natywnych technologii.

Społeczność

Jedną z głównych zalet rozwiązań OpenSource jest społeczność, która stoi za danym projektem. To właśnie do niej będziemy się zwracać, kiedy pojawią się pierwsze problemy podczas developmentu. Od tego, czy społeczność jest aktywna, zależy również ilość dostępnych gotowych komponentów do wykorzystania.

Jeżeli społeczność jest zbyt mała albo nieaktywna, sami będziemy musieli rozwiązywać wiele problemów, a może również się zdarzyć, że projekt zwyczajnie umrze śmiercią naturalną.

Apache Cordova (dawniej PhoneGap)

Apache Cordova

Apache Cordova

PhoneGap to jeden z najstarszych i najbardziej znany framework aplikacji hybrydowych, dlatego po prostu musi pojawić się w każdym zestawieniu.

Przy pomocy tego narzędzia budowana jest natywna aplikacja opakowująca na konkretny system operacyjny. Wewnątrz wrappera logika biznesowa aplikacji zrealizowana jest przez HTML, CSS i JavaScript, a możliwości samego JavaScriptu rozszerzone są o dostęp do natywnych funkcjonalności urządzenia.

Nad rozwojem projektu na wolnej licencji Apache 2.0 czuwa przede wszystkim Adobe Systems.

Projekt ma bardzo aktywną i liczną społeczność oraz ogromną bazę istniejących pluginów, gdyby jednak i ona okazała się niewystarczająca, zawsze można dopisać własne rozszerzenie.

Ponieważ powstała aplikacja jest również stroną www, podstawowe jej mechanizmy oraz wygląd można testować w zwykłej przeglądarce.

Cordova wspierane funkcjonalnosci

Cordova wspierane funkcjonalnosci (źródło: cordova.apache.org)

 

Ionic

Ionic

Ionic

Ionic to  kompletne SDK przeznaczone do wytwarzania aplikacji mobilnych. Zbudowany jest z wykorzystaniem Apache Cordova oraz AngularJS.

Projekt rozwijany na licencji MIT. Ponieważ swoje działanie opiera na PhoneGap, odziedziczył również po nim ogromną bazę dostępnych pluginów i społeczność.

Pisanie aplikacji w Ionic przypomina trochę składanie strony www z gotowych klocków udostępnionych za darmo lub odpłatnie na Ionic Market.

Sencha Touch

Sencha Touch

Sencha Touch

Sencha Touch to framework napisany i wspierany przez twórców Ext JS, do swojego działania wykorzystuje HTML 5. Wspierane systemy operacyjne to między innymi: iOS, Android, BlackBerry oraz Windows Phone. Framework dostępny jest na podwójnej licencji Commercial License oraz GPLv3.

Kendo UI

Kendo UI

Kendo UI

Kendo UI to kolejny framework napisany z wykorzystaniem HTML 5 oraz biblioteki jQuery. Niestety znaczna część nawet podstawowych komponentów jest dostępna tylko odpłatnie.

React Native

React native

React native

React Native to nie jest typowy framework hybrydowy. Aplikację piszemy co prawda z wykorzystaniem JavaScript, ale na jego podstawie generowane są natywne komponenty. W efekcie czego aplikacje powstałe przy pomocy tego frameworka są tylko nieznacznie wolniejsze od natywnych.

Mimo braku możliwości testowania aplikacji w przeglądarce sam development i podglądanie zmian są również bardzo szybkie dzięki możliwości przeładowania komponentów, bez konieczności budowania całego projektu.

Kod powstały z wykorzystaniem biblioteki React zawiera pomieszane fragmenty logiki biznesowej oraz widoku, co może być dla niektórych odstraszające.

Projekt ma wsparcie bardzo silnej i aktywnej społeczności, jest również wspierany przez developerów Facebooka. Przekłada się to na dużą bazę dostępnych komponentów. Ciekawostką jest to, że przy jego pomocy można również wykorzystać istniejące pluginy z PhoneGap.

Intel XDK

Intel XDK

Intel XDK

Intel XDK to rozwijane przez Intel środowisko do tworzenia wieloplatformowych aplikacji mobilnych z wykorzystaniem HTML5, CSS, JavaScript oraz Apache Cordova.

Ionic vs React Native

Z przedstawionych tu możliwości najbardziej przypadły mi do gustu dwa: Ionic oraz React Native. Za jednym i drugim rozwiązaniem stoi bardzo silna społeczność i bogata baza gotowych funkcjonalności.

Oba frameworki wykorzystują również znane i bardzo dobre technologie:

  • Ionic – Cordova i AngularJS od Google
  • React Native – React od Facebooka.

Ponieważ obie technologie spełniają moje oczekiwania, przed ostateczną decyzją przeprowadzę jeszcze jeden test. Napiszę dwie proste aplikacje realizujące tę samą funkcjonalność w obu technologiach. Framework, z którego będzie mi się lepiej korzystało, zostanie wykorzystany do projektu StormSnapshot.

4 komentarze
Share:
Kurs aplikacje mobilne

Kurs tworzenia i projektowania aplikacji mobilnych -> StormSnapshot #1

W poprzedniej części cyklu StormSnapshot zebraliśmy wymagania wobec naszej aplikacji. Dzisiaj chciałbym przedstawić Wam dylematy związane z tworzeniem aplikacji mobilnych. W kolejnych krokach zastanowimy się, na jakich technologiach oprzeć naszą aplikację.

Co to jest aplikacja mobilna?

Zacznijmy od prostej definicji. Aplikacja mobilna to oprogramowanie działające na urządzeniach przenośnych, czyli przede wszystkim na różnych smartfonach, czy tabletach.

Aplikacje mobilne – od czego zacząć?

Decydując się na programowanie aplikacji mobilnych, musisz dokonać wielu wyborów. Jedną z najważniejszych decyzji, jest wybranie obsługiwanych platform oraz język programowania i konkretne frameworki, przy pomocy których powstanie aplikacja.

W tekście zebrałem niezbędne informacje tak, by podjęta decyzja była bardziej świadoma.

Jak wygląda rynek aplikacji mobilnych?

Rynek aplikacji mobilnych, delikatnie mówiąc, jest skomplikowany. Jest to niestety przeciwieństwo zwykłych aplikacji webowych, gdzie raz napisana aplikacja z wykorzystaniem HTMLa i JavaScriptu, może zostać uruchomiona na praktycznie dowolnej przeglądarce internetowej.

W przypadku programowania aplikacji mobilnych musimy brać pod uwagę nie tylko możliwości samego urządzenia, na którym będzie działała nasza aplikacja, ale również jego system operacyjny.

Systemy mobilne Polska

Systemy mobilne Polska (źródło: statcounter.com)

Systemy mobilne świat

Systemy mobilne świat (źródło: statcounter.com)

Systemy operacyjne Polska

Systemy operacyjne Polska (źródło: statcounter.com)

Na początek 2017 roku w Polsce mamy 3 głównych graczy, jeżeli chodzi o mobilne systemy operacyjne:

  • Android – niekwestionowany lider, prawie 90% rynku!
  • Windows Phone – około 5%;
  • iOS  – około 2%;

Wyraźnie widać, że Polska została całkowicie zdominowana przez system operacyjny od Google. Jednak jeżeli spojrzymy na statystyki z punktu widzenia całego świata, większego znaczenia nabiera również system od Apple.

Ciekawostką jest to, że Android jest w Polsce najpopularniejszym systemem, nawet jeżeli pod uwagę weźmiemy komputery stacjonarne.

Polska czy świat?

Na podstawie tych statystyk widać, że trzeba sobie zadać pytanie, czy aplikacja ma być przeznaczona tylko dla użytkowników z Polski, czy raczej celujemy w globalny rynek.

Zrozumiałe jest to, że chcielibyśmy dotrzeć do jak największego grona odbiorców. Jeśli jednak aplikacja ma być dostępna tylko w Polsce, sytuacja nie jest już tak oczywista. Warto zastanowić się, czy z punktu widzenia ekonomicznego bardziej opłacalne nie będzie ograniczenie się tylko do Androida. Stracimy co prawda część rynku, ale możemy wtedy skupić się tylko na jednej platformie.

Natywna aplikacja mobilna

Aplikacja natywna, czyli taka, która została od podstaw napisana w języku programowania specyficznym dla danej platformy:

  • Android – Java
  • iOS – Objective C
  • Windows Phone – C#

Jest to standardowe podejście do programowania, mianowicie jeden system operacyjny – jedna aplikacja. Niestety każda platforma to całkowicie inny świat programistyczny. Dlatego pisząc aplikacje natywne, utrzymujemy kilka niezależnych aplikacji, w różnych językach.

Tylko kogo na to stać…

Idziemy na kompromis – aplikacje hybrydowe

Aplikacje hybrydowe są swego rodzaju kompromisem między możliwościami, jakie dają aplikacje natywne a kosztem wytwarzania i utrzymania oprogramowania. Jeżeli nie możemy sobie pozwolić na rozwijanie kilku niezależnych aplikacji i jednocześnie chcemy udostępnić nasze działo szerszemu gronu, powinniśmy zainteresować się właśnie aplikacjami hybrydowymi.

Hybrydy pisane są najczęściej z wykorzystaniem technologii przeznaczonych do budowania aplikacji internetowych (HTML, JavaScript), jednak za pomocą specjalnie spreparowanego API mają również dostęp do natywnych funkcjonalności telefonu, jak kamera, czy odbiornik GPS.

Z czego musimy zrezygnować?

Niestety w życiu nie ma nic za darmo. W tym przypadku też musimy z czegoś zrezygnować, żeby cieszyć się możliwościami aplikacji hybrydowych.

Tego typu aplikacje z racji wprowadzenia dodatkowej warstwy abstrakcji, są zazwyczaj wolniejsze. Jednak dzisiejsze telefony są już na tyle szybkie, że w większości wypadków nie ma to tak dużego znaczenia.

Kolejny minus takich rozwiązań wynika bezpośrednio z ich specyfiki. Ponieważ te aplikacje muszą działać na kilku różnych systemach, funkcjonalności, które oferują, muszą być dostępne na wszystkich platformach. Wszelkie specyficzne rzeczy nie będą zwyczajnie obsługiwane.

To ograniczenie w pewnym stopniu można obejść. Trzeba jednak przygotować specyficzne fragmenty kodu dla różnych systemów, np. w formie pluginów.

Apache Cordova (PhoneGap)

Najbardziej popularny przedstawiciel tej kategorii to Apache Cordova (dawniej PhoneGap).  Raz napisana aplikacja przy pomocy HTML i JavaScript jest opakowywana w web view i udostępniana w formie zwykłej aplikacji na daną platformę.

Jaki typ aplikacji wybrać?

Natywne

Brak pośrednich technologii i brak dodatkowych narzutów jest niewątpliwie kuszącą opcją. Dlatego, jeżeli ze względu na koszty możemy pozwolić sobie na utrzymywanie kilku aplikacji lub jeżeli decydujemy się tylko na jedną platformę, warto wybrać aplikacje natywne.

Hybrydowe

Jeżeli jesteśmy w stanie iść na pewne kompromisy, to decydując się na aplikacje hybrydowe, oszczędzimy bardzo dużo czasu i pieniędzy.

StormSnapshot – czas wyboru

Aplikacja StormSnapshot docelowo będzie rozwijana w co najmniej dwóch językach: po polsku i angielsku. Chciałbym również, żeby była dostępna dla użytkowników z całego świata. Z przedstawionych wcześniej statystyk wynika, że powinienem zainteresować się przynajmniej dwiema platformami: Android oraz iOS.

Ponieważ nie chcę przeznaczyć na ten projekt tyle czasu, by rozwijać dwie aplikacje, a dodatkowo nie znam Objective C, najlepszym wyborem wydaje się aplikacja hybrydowa.

W kolejnym tekście zastanowimy się nad możliwościami konkretnych frameworków dla aplikacji hybrydowych i wybierzemy ten spełniający nasze oczekiwania.

No comments
Share:
START -> StormSnapshot

START -> StormSnapshot #0

Miło mi zaprezentować nową serię postów, która będzie prowadzona w ramach tego bloga.

Seria StormSnapshot będzie pisana w formie kursu, a po każdym artykule będzie dostępna nowa wersja kodu do samodzielnej analizy. Na koniec powstanie w pełni funkcjonalna aplikacja.

Co to za aplikacja?

StormSnapshot to aplikacja mobilna przetwarzająca video w czasie rzeczywistym. Aplikacja wprowadza filtry na obraz pobrany z kamery.

Ten krótki akapit to esencja tego, jak aplikacja ma działać z punktu widzenia użytkownika. Rozbudujmy to jednak trochę w formie założeń projektowych.

Założenia projektowe

Każdy projekt musi mieć jakieś wymagania, tak będzie i tym razem. Ponieważ projekt nie ma zewnętrznego klienta, sam musiałem je sobie narzucić.

Gotowy produkt

Chciałbym, żeby na koniec tej serii został przedstawiony w pełni działający i funkcjonalny produkt, który będzie można zaprezentować np. w portfolio. Jest to mój najważniejszy wymóg.

Aplikacja mobilna

Aplikacja powinna być dostępna na urządzenia mobilne. Nie określam jeszcze, jakie to będą platformy, ustalimy to w kolejnym tekście.

Konkurs DSP

Projekt został zgłoszony do konkursu dajsiepoznac.pl, co dodatkowo wymusza rygor przynajmniej 2 postów technologicznych w tygodniu, w tym minimum 1 na temat samego projektu.

DSP 2017

DSP 2017

Zmienność

Wszystkie zebrane tu założenia są płynne. Jeżeli podczas trwania projektu okaże się, że coś można zmienić lub udoskonalić, oczywiście to zrobimy.

Forma wpisów

W ramach projektu będę udostępniał wpisy typowo techniczne, omawiające konkretne zmiany wprowadzone w aplikacji oraz teksty bardziej ogólne, związane z analizą rozwiązań i problemów.

Wszystkie wpisy będą jednak stanowiły jedną spójną całość, a każdy kolejny tekst będzie wynikał z poprzednich. Do ich zrozumienia będzie wymagana podstawowa wiedza z zakresu Javy, dlatego zacznij proszę od zapoznania się z kursem Javy.

Technologie

Konkretne technologie przedstawię w kolejnych wpisach, jednak na ten moment mogę określić, że będzie on rozwijany w Javie. Wybór konkretnych frameworków będzie podyktowany wcześniejszą analizą, którą wspólnie przeprowadzimy.

Repozytorium projektu

Wszystkie źródła będą dostępne na GitHub.

Dodatkowo dla każdego wpisu zostanie wydzielony osobny branch, żeby również po zakończeniu projektu można było łatwo prześledzić, jak on był rozwijany.

Jeżeli potrzebujesz powtórki z gita możesz zajrzeć do wpisu: Git tutorial.

Podsumowanie

Zapraszam do wspólnej realizacji tego lub podobnego projektu. Jeżeli macie jakieś uwagi odnośnie założeń, czekam na komentarze.

No comments
Share: