Transforme seu site (PWA ou não) em aplicativo na Play e App Store

06 Mar • Escrito por @lhas

Hoje você vai aprender uma solução bala de prata pra resolver a dor de muito cliente por aí.

“Os usuários vão encontrá-lo na Play/App Store?”, o cliente, otimista, pergunta.

Você, com aquela cara de confuso, explica que não, não vai rolar.

SEUS PROBLEMAS ACABARAM!1!11!

Hoje, eu vou te dar o caminho das pedras para resolver esse problema de uma vez por todas.

Não é das soluções mais elegantes, com certeza.

Porém, essa solução permite que você faça deploy do seu app nas lojas apenas uma vez (ou mais vezes, caso você queira trocar o ícone e/ou a splash screen do aplicativo).

A sua aplicação em si continua sendo a sua versão Web.

Ter uma base de código única que sirva múltiplas plataformas é o sonho molhado de qualquer desenvolvedor web nos últimos anos.

É a solução oficial de aplicativos como o Instagram Lite e o Twitter Lite.

Requisitos

Vamos precisar editar uns arquivos em JavaScript mas você não precisa ser nenhum expert no assunto para entender o que está acontecendo.

Dito isso, precisaremos de:

Iniciando o projeto

Vamos criar a estrutura inicial da nossa aplicação que serviŕa de wrapper para o nosso site:

$ expo init 01dev # substitua 01dev pelo nome do seu projeto

Será solicitado um template a ser usado. Eu recomendo o blank (TypeScript) mas pode ser qualquer um..

Após escolher o template, todas as dependências do template serão instaladas.

Vamos rodar o projeto:

cd 01dev
yarn start

O nosso projeto irá rodar o Expo Developer Tools, uma ferramenta no browser que inicializará todos os serviços necessários para que nossa aplicação rode no ambiente de desenvolvimento.

Agora precisaremos rodar o nosso aplicativo. Você pode usar um emulador Android ou seu próprio celular baixando o aplicativo do Expo.

Se você optar pelo emulador, esse é o momento para rodá-lo. Com o emulador rodando, vamos clicar em “Run on Android device/emulator…” e o nosso aplicativo será inicializado, como demonstrado abaixo:

Com o aplicativo rodando, podemos editar o nosso arquivo App.tsx, removendo todo o código desnecessário dele:

import React from "react"
- import { StyleSheet, Text, View } from "react-native"
+ import { Text, View } from "react-native"

export default function App() {
  return (
-    <View style={styles.container}>
+    <View>
      <Text>Open up App.tsx to start working on your app!</Text>
    </View>
  )
}

- const styles = StyleSheet.create({
-   container: {
-     flex: 1,
-     backgroundColor: "#fff",
-     alignItems: "center",
-     justifyContent: "center",
-   },
})

Instalando o WebView

Para renderizar o nosso site dentro dessa “casca”, vamos precisar de um componente chamado WebView.

Este componente antigamente fazia parte do core do react-native, porém desde as últimas versões ele foi isolado em uma dependência a parte.

Por conta disso, vamos adicioná-lo a nossa lista de dependências:

$ expo install react-native-webview

Usando o WebView

Com o nosso componente instalado, vamos usá-lo editando o App.tsx:

import React from "react"
+ import { WebView } from "react-native-webview"
- import { StyleSheet, Text, View } from "react-native"
+ import { View } from "react-native"

export default function App() {
  return (
-    <View>
+    <View style={{ flex: 1 }}>
-       <Text>Open up App.tsx to start working on your app!</Text>
+       <WebView source={{ uri: "https://01dev.codes" }} />
    </View>
  )
}

Pronto! Nosso WebView já estará funcionando. Porém, nem tudo são flores.

Se você é uma pessoa com TOC que nem eu, você vai notar que as vezes a splash screen vai sumir antes do site terminar de carregar. E esse processo vai mostrar uma tela branca temporária pro nosso usuário final, que não sabe o que está acontecendo.

Ocultando Splash Screen após site carregar

Existe uma maneira de ocultarmos a SplahScreen programaticamente (ou seja, somente quando nós quisermos).

Além disso, o nosso componente de WebView nos fornece um callback de onLoadEnd, que é acionado quando a página termina de concluir 100%.

Pegou a ideia? Vamos unir o útil ao agradável:

- import React from "react";
+ import React, { useEffect } from "react";
import { WebView } from "react-native-webview";
import { View } from "react-native";
+ import { SplashScreen } from "expo";

export default function App() {

+   useEffect(() => {
+       SplashScreen.preventAutoHide();
+   }, []);

+   const onLoadEnd = () => {
+       SplashScreen.hide();
+   };

  return (
    <View style={{ flex: 1 }}>
-      <WebView source={{ uri: "https://01dev.codes" }} />
+      <WebView source={{ uri: "https://01dev.codes" }} onLoadEnd={onLoadEnd} />
    </View>
  );
}

Deixando em tela cheia

Você vai notar que o WebView está carregando embaixo da StatusBar do Android:

Screenshot 20200306 173813

Uma maneira de resolvermos isso, é pegar a altura do StatusBar e adicionar um espaçamento interno na View com essa altura:

import React, { useEffect } from "react";
import { WebView } from "react-native-webview";
- import { View } from "react-native";
+ import { StatusBar, View } from "react-native";
import { SplashScreen } from "expo";

export default function App() {

  useEffect(() => {
      SplashScreen.preventAutoHide();
  }, []);

  const onLoadEnd = () => {
      SplashScreen.hide();
  };

  return (
-    <View style={{ flex: 1 }}>
+    <View style={{ flex: 1, paddingTop: StatusBar.currentHeight }}>
      <WebView source={{ uri: "https://01dev.codes" }} onLoadEnd={onLoadEnd} />
    </View>
  );
}

Resolvido! Você também pode adicionar um backgroundColor para preencher o fundo do StatusBar com alguma cor do seu projeto:

-    <View style={{ flex: 1, paddingTop: StatusBar.currentHeight }}>
+    <View style={{ flex: 1, paddingTop: StatusBar.currentHeight, backgroundColor: 'rgb(0, 125, 146)' }}>

Screenshot 20200306 174346

Toques finais do app

Você precisa dar um toque final para que as lojas consigam interpretar o seu aplicativo corretamente.

Para isso, vamos editar arquivo de app.json na raíz do projeto.

O mais importante a se editar aqui, caso você pretenda gerar um APK para o Android, é adicionar o seguinte:

{
  "expo": {
    "name": "Blank Template (TypeScript)",
    "slug": "01dev",
    "privacy": "public",
    "sdkVersion": "36.0.0",
    "platforms": [
      "ios",
      "android",
      "web"
    ],
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true
    },
+    "android": {
+     "package": "com.yourcompany.yourappname",
+     "versionCode": 1
+   }
  }
}

Atualize o package para um nome único do seu aplicativo.

Obs: O versionCode deve ser atualizado cada vez que você publicar uma versão nova na Play Store (precisa ser um número inteiro). Se não, a Play Store vai acusar que você está tentando subir a mesma versão.

Gerando APK (ou IPA)

Para gerar um bundle assinado para o Android (APK), basta rodar na pasta do projeto:

$ expo build:android

Para gerar um bundle assinado para a Apple (IPA), basta rodar na pasta do projeto:

$ expo build:ios

A primeira pergunta que o CLI vai ser no primeiro build é se você gostaria de upar um keystore ou prefere que o próprio Expo cuide disso pra ti.

Como esse é um tutorial para iniciantes, super recomendo manter a opção 1), mantendo o Expo como gerador de keystores.

Em algum momento, o processo de build estará nesse estado:

Screenshot 20200306 180227

É só abrir o link que o Expo te libera (esse é um link de exemplo) para que, quando o processo de build esteja 100% concluído, você possa baixar seu APK.

Basta clicar em Download para ter acesso ao seu APK:

Screenshot 20200306 180427

Alterando o ícone e o Splash Screen

Você provavelmente vai querer customizar o ícone e a splash screen do seu aplicativo.

Para o ícone, você precisará de uma imagem no formato PNG com dimensões de 192x192px.

Para a Splash Screen, você precisará de uma imagem no formato PNG com dimensões de 1242x2436px.

Com as imagens em mãos, basta atualizá-las em assets/icon.png e assets/splash.png, respectivamente.

Observação: Você provavelmente vai querer mudar o resizeMode da splash screen para cover no nosso app.json:

"splash": {
    "image": "./assets/splash.png",
-    "resizeMode": "contain",
+    "resizeMode": "cover",
    "backgroundColor": "#ffffff"
},

Publicando o aplicativo na Play Store

Você precisará de uma conta na Google Play Console.

Na tela de “Todos os apps”, basta clicar em “Criar App” e seguir todas as instruções.

Você vai precisar preencher algumas abas que são obrigatórias, como Gerenciamento de Versão, Presença na loja, Classificação de Conteúdo, entre outros.

Com todas as abas preenchidas, basta ir em “Gerenciamento de Versão” -> “Versões de Apps”.

Clique em “Gerenciar” na “Faixa de Produção”. Depois, clique em “Criar uma versão”.

Aqui é onde iremos anexar o nosso arquivo APK gerado pelo Expo:

Screenshot 20200306 181105

Conclusão

Esse é um dos métodos que permitem que você publique seu site, PWA ou não, nas lojas oficiais da Apple e da Google.

Como a base de código é em React Native, você pode inclusive implementar ferramentas extras, como Push Notifications (usando o Firebase).

Espero que tenham gostado e até a próxima! 😺


Escrito por

Luiz Almeida

Especialista em front-end, trabalha com desenvolvimento há 10 anos. Apaixonado por escrever e participar de desafios que envolvem tecnologia, vive atualmente em Porto Alegre.

LinkedIn Instagram