NLW2 Proffy Mobile

Next Level Week


Project maintained by shyoutarou Hosted on GitHub Pages — Theme by mattgraham

Aula 4 (06/08/2020) - Estruturando app mobile

Videos Youtube

  1. Trilha OmniStack

Wikis

Resumo dos últimos dias da NLW da Rocketseat.

Wiki Home

GitHub Pages

GitHub Pages Web

Interface Mobile

Para o desenvolvimento mobile iremos utilizar a biblioteca expo, para criar o projeto mobile digite no PowerShell:

expo init mobile

E escolha a opção:

blank (TypeScript)    same as blank but with TypeScript configuration

Image

Quando criamos um projeto React Native que não seja pelo Expo, é possível iniciar um projeto React Native com Typescript, executando o comando:

npx react-native init authrn --template react-native-template-typescript

Com npx ele busca o pacote na web instala na sua máquina na versão mais atualizada, executa o comando react-native, deixa em cache por um tempo e depois desinstala, dessa forma você não precisa ficar com o react-native cli na node_modules principal da sua máquina. O template Typescript vem da flag: –template react-native-template-typescript. Porém a estrutura do projeto e as estratégias do desenvolvimento da aplicação diferem.

Image

Repare principalmente que o projeto expo não tem as pasta android e ios. No projeto criado pelo npm, ao querer depurar o app pelo emulador é necessário, para instalação do app no emulador, emitir o comando:

npx react-native run-android

Como no projeto expo não existe a pasta android, acontece o seguinte erro:

Image

error Android project not found. Are you sure this is a React Native project? If your Android files are located in a non-standard location (e.g. not inside 'android' folder), consider setting `project.android.sourceDir` option to point to a new location. Run CLI with --verbose flag for more details.

Ao pesquisar na Internet sobre o problema vai levar a vários tópicos que vão indicar para atualizar o react-native, o que vai levar a outra sucessão de erros:

Image

No projeto Expo, que faz a interface com o navegador é o Metro Builder pelo navegador, e é ele que oferece as opções de depuração da aplicação. Porém para dispositivos físicos, aparentemente, não diferenças no desenvolvimento.

Image

Dentro da pasta do projeto digite:

yarn add expo OU npm install expo

Image

Depois digite:

yarn start OU npm start

Image

Que vai abrir o browser para visualizar os logs da aplicação, quais celulares disponíveis estão debugando, etc.

Image

Quais celulares disponíveis estão debugando, etc.

Image

Para listar emuladores podemos aplicar o comando:

emulator –list-avds

Image

E para iniciar um emulador:

emulator –avd Nome_Emulador

O importante é o endereço abaixo que permite testarmos a aplicação:

exp://192.168.0.101:19000

Para testar com o QR Code temos que instalar o app Expo cliente no celular:

Image

To run the app with live reloading, choose one of:
    -Scan the QR code above with the Expo app (Android) or the Camera app (iOS).
    -Press a for Android emulator, or w to run on web.
    -Press e to send a link to your phone with email.
    -Press s to sign in and enable more options.

Com este QR Code é possível passar para outras pessoas com o expo instalado para poderem avaliar seu aplicativo pronto:

Image

Para testar no emulador podemos ver o vídeo do link antes pra saber como instalar para React Native: emulando-react-native-no-iosandroid-com-expo

O expo pode dar muitos problemas de configuração, tem limitações de proxy e Firewall, mas dá pra consultar alguns deles em: expo-common-issues

Como podemos ver a estrutura do programa mobile e igual a da Web: JSX (Javascript + XML) e funções retornando Elementos gráficos com componentes utilizando os estados e propiedades. Porém estes elementos não são HTML puro e sim componentes pré-criados pela biblioteca do Native (StyleSheet, Text, View) e todos elementos tem display flex por padrão. O css também não existe (classes, ids) e nem herança de estilos. Cria-se um estilo particular e identificado por elemento. Não há parte de animações, nem gradientes, grid tem que fazer na unha.

Image

A única exceção de herança de estilo é quando se coloca componentes Text aninhados como abaico:

Image

Por padrão, o Native também não lê arquivos de imagem svg só png. Teria que instalar uma extensão. No mobile tem o conceito de densidade de pixels e temos que exportar as imagens em 3 tamanhos que o Native reconhece a resolução pelo nome …2x, 3x, etc. Antes de existir o React, não era possível o Javascript reconhecer imagens. Para fazer a aplicação reconhecer arquivos png precisamos criar uma pasta @type em src com um arquivo index.d.ts com a seguinte declaração: declare module ‘*.png’;

Image

Crie uma pasta src e dentro dela a pasta pages. Dentro dessa pasta teremos as páginas igual o que foi feito na aplicação web. Comece criando a página/pasta Landing com os arquivos index.tsx e styles,ts (não mais css)

Image

No arquivo principal App.tsx vamos prepara-lo para receber o componente Landing. Como não é possível “empilhar” os companentes Landing e StatusBar sem que haja alg envelopando-os, aqui podemos fazer de duas formas principais:

Image

A vantagem do Fragment é que não irá renderizar mais uma View, pois de Landing já está retornando outra View.

Para instalar as fontes usadas no projeto Web (Archivo e Poppins) faça o seguinte comando:

expo install @expo-google-fonts/archivo @expo-google-fonts/poppins

Image

Após feito isso, na página App.tsx importe as fontes e o módulo AppLoading:

import { AppLoading } from 'expo'
import { Archivo_400Regular, Archivo_700Bold, useFonts } from '@expo-google-fonts/archivo'
import { Poppins_400Regular, Poppins_600SemiBold } from '@expo-google-fonts/poppins'

Na mesma página, declare globalmente as variáveis e faça um condicional para verificar se as fontes foram carregadas:

Image

Por fim, é so utilizar nas StyleSheets de qualquer página.

Image

Inicialmente, para criar os botões podemos utilizar o TouchableOpacity, importando do React Native.

import {View, Image, Text, TouchableOpacity} from 'react-native'

E aplicando nos botões ficaria como abaixo. Repare que o style recebe um array de estilos, permitindo 2 estilos aproveitarem um estilo básico simulando a flexibilização de uma herança.

Image

Rota no React Native

Para navegar vamos instalar a biblioteca React Native digitando:

yarn add @react-navigation/native OU npm install @react-navigation/native

Image

Depois temos que instalar as dependências em relação ao expo:

expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

Image

A 3 tipos principais de navegação React:

Precisamos instalar então a navegação stack e bottomtabs:

yarn add @react-navigation/stack OU npm install @react-navigation/stack

Image

yarn add @react-navigation/bottom-tabs

Image

Criamos então uma pasta routes dentro de src e criamos duas páginas AppStack.tsx e StudyTabs.tsx uma pra cada tipo de navegação. A AppStack.tsx conterá as chamadas das páginas sem Tabs Landing e GiveClasses e a página com as Tabs StudyTabs. E por fim, nosso AppStack tem retornar um NavigationContainer contendo as telas(Screen) conforme a documentação.

Image

A StudyTabs terá o direcionamento para duas páginas TeacherList (aba Proffys) e Favoritos. Na StudyTabs conterá o conteúdo e o visual (style.ts) das tabs.

Image

Repare no módulo Ionicons que traz umas biblioteca de ícones padrão para celular. ionicons

Image

Poderia ter sido utilizado o icons do: feathericons

Image

Qualquer deles pode ser acessado pela biblioteca do expo:

import { Ionicons } from '@expo/vector-icons'
import { Feather } from '@expo/vector-icons';
<Ionicons name="ios-easel" size={20} color= '#fff'/>
<Feather name="filter" size={20} color="#fff" />

E que a estilização do tab tem ser feita pela propriedade tabBarOptions do Navigator

Image

Image

As duas páginas devem conter conteúdo similar que irá ter o conteúdo (index.tsx) e o visual (style.ts) das páginas.

Image

Com isso, já podemos navegar. Na página Landing import useNavigation da React Navigation:

import { useNavigation } from '@react-navigation/native'

Crie as funções que serão associando aos botões de navegação e indique a rota:

Image

Finalmente, atribua os métodos aos botões.

Image

Aula 5 (07/08/2020) - Finalizando app mobile

Conectando Mobile

Precisamos instalar novamente a biblioteca que facilita o consumo de API externas pela aplicação: yarn add axios

Image

Como no projeto Web, crie uma pasta services e dentro dela o arquivo api.ts.

Image

O IP que utilizamos é o disponibilizado pelo Metro Bundler abaixo que permite testarmos a aplicação. Lembre-se que sempre que trocar de máquina, deve-se atualizar este número para testar na máquina atual.

192.168.0.101:3333

Image

Isso é necessário pois o localhost pode não ser acessível na rede, então é necessário utilizar o IP. Em um terminal paralelo, navegue até a pasta do servidor e inicie-o com o comando yarn start. Depois teste com o Insomnia a conexão:

Image

A chamada da API na aplicação mobile é idêntica a da web.

Image

Image

Já nos componentes de filtro da página TeacherList, uma diferença é que invés de Onchange está se usando OnchangeText, mas isso porque, por razões de tempo, não foi implementado a caixa de seleção (ficando como um dos Desafios mais adiante).

Image

Para testar o botão de filtro é possível fazer a mesma estratégia de emitir um console.log no método relacionado:

Image

Image

Única coisa a se lembrar é de trocar o aparelho que estiver se testando, se for emulador ou aparelho físico.

Image

Feito isso o método é idêntico ao do projeto web:

Image

Image

WhatsApp – Deep Linking

No botão do WhatsApp vamos aplicar uma técnica conhecida como “Deep Linking” onde uma aplicação abre outra aplicação. Grande parte de aplicação mobile tem um endereço URL em que é possível acessar pelo módulo do React Native Linking:

import { View, Image, Text, Linking, AsyncStorage } from 'react-native'; 

Image

Favoritos – Armazenamento Interno

Para armazenamento interno no mobile precisamos instalar um DB pelo:

expo install @react-native-community/async-storage

Image

Temos que criar a propriedade no componente TeacherItem para sabermos quando foi favoritado e fazer as mudanças necessárias no Layout.

Image

Image

O favoriteArray.push adiciona o item no Array de favorito, o splice remove o conteúdo da lista. No botão dos favoritos há apenas um condicional trocando a imagem do botão favorito:

Image

Na página TeacherList precisamos de uma variável constante de estado, para acompanhar as mudança no controle salvando a id do professor.

const [favorites, setFavorites] = useState<number[]>([]);

Image