Domar a fera. O que enfrentamos ao desenvolver um aplicativo de diário pessoal no React Native

Em um artigo anterior, falei detalhadamente sobre nossa experiência na criação de um serviço web / aplicativo móvel para manter um diário pessoal. A versão atual do aplicativo (a versão mínima viável já está disponível no Google Play) está sendo desenvolvida no React Native, e aqui vamos falar sobre ele hoje em detalhes.

Falamos sobre nossa própria experiência com a estrutura, maneiras de expandir a funcionalidade, “armadilhas” (onde você está sem elas!) E como as contornamos.

Sobre toda a estrutura


Um pouco sobre o herói da ocasião - React Native . Ele ainda é bom!

Para quem conhece JavaScript o suficiente e principalmente o NodeJS - é muito bom. Se você tem experiência com React, bem, ou pelo menos tem uma compreensão de sua ideia, mecanismo - é simplesmente magnífico!

O principal é que a saída é um aplicativo verdadeiramente nativo. Extensões e plug-ins cobrem quase 99% das tarefas típicas. A porcentagem restante em caso de necessidade urgente pode ser adicionada nos idiomas nativos (java, object-c) e conectada ao aplicativo React Native.

Mas o suficiente sobre os profissionais, eles não lhes são úteis, embora a lista seja impressionante. Todas as guloseimas e guloseimas não fazem sentido se o aplicativo não for iniciado, e esta é a primeira coisa que "agradamos" ao React Native.

No começo, ele não gostou da versão do NodeJS. Então a versão npm. Em seguida, a versão do Android SDK, a versão das ferramentas do Android e então ... Não há nenhum ponto em escrever sobre como todos os problemas foram resolvidos, porque a partir desse momento todo o software acima atualizou suas versões e as instruções serão irrelevantes.

Esteja ciente: o gargalo do React Native é o ambiente de construção. Prepare-se para aprender no Google, ler fóruns e fluxo de pilha. Como resultado, gastamos na implantação: Ubuntu - 3 dias, Win10 - 2 dias. Por mais estranho que pareça, tudo acabou sendo mais simples no Windows, bem, ou simplesmente no ubuntu, eles se livraram dos cones e já entendiam o que e onde se livrar.

Observe que de repente alguém se torna útil: o código apresentado abaixo resolveu todos os problemas com a compatibilidade das versões sdk dos complementos ao compilar o projeto.

subprojects { afterEvaluate {project -> if (project.hasProperty("android")) { android { compileSdkVersion 26 buildToolsVersion '26.0.3' } } } } 

Está escrito no arquivo /android/build.gradle no final. Sem essa "diretiva", aparentemente, cada um dos plugins / extensões tentou compilar de acordo com suas próprias versões do Android SDK, o que levou à montagem do projeto em uma variedade caótica de erros ferozes e avisos desagradáveis. Ninguém sabe quão relevante será a recomendação no futuro. Hoje, porém, especialmente depois que o Google proibiu o uso de SDKs abaixo da 26ª revisão para compilação, isso ajuda muito.

O segundo gargalo - a dor não é tanto o React Native, como, aparentemente, todo o Open Source como um todo - suporte limitado. Os repositórios têm toneladas de problemas não resolvidos. Bots "inteligentes" ferozes fecham bugs na ausência de atividade, às vezes mesmo após 7 dias ... E tudo parece estar bem. Ninguém deve nada a ninguém. Todo mundo está acostumado.

entrada de texto about.me

A paciência foi interrompida quando um "erro" foi descoberto ao inserir um texto banal em um TextInput comum. Apenas uma caixa de texto. Apenas entrada de texto do teclado na tela. Após alguns minutos de impressão, começam os terríveis atrasos e freios do sistema. Corremos para procurar um problema - sim, existe um, começou com a versão RN 5x.xx Você resolve o problema? Não. Duas ou três questões sobre o tópico são simplesmente encerradas. Mais alguns se fundiram em um grande .

Eu tive que cavar por dentro, descobrir, tentar várias opções, mudar as versões do RN, na esperança de que não houvesse um batente lá. Como resultado, foi experimentalmente possível minimizar as falhas de desempenho - eles removeram completamente toda a formatação e reescreveram o manipulador de entrada. Mas o resíduo desagradável permaneceu. O problema com os desenvolvedores do framework, a propósito, não foi resolvido até agora, seis meses se passaram ...

Banco de Dados


O Realm é um banco de dados rápido, com funcionalidade impressionante e funcionando no Android, IOS, Windows.

No começo, havia um sentimento duplo, dizem eles, não há ORM para você, realmente não existe sql, a gravação é apenas dentro do retorno de chamada. Incomum e estranho, especialmente para um desenvolvedor web originalmente do PHP, que cresceu no ActiveRecord e no Doctrine. Mas, de fato, a elaboração do seu conjunto mínimo de funções para CRUD acabou sendo bastante simples e rápida. E todas as questões de gosto e hábitos foram resolvidas lendo as informações oficiais, concisas, concisas e compreensíveis.

E então o carrossel de presentes começou:

  • Criptografia de dados, pronta para uso
  • Carregamento lento de dados (extrai do banco de dados apenas o necessário agora)
  • Relações reais entre entidades (oi mongo!
  • Controle de versão da estrutura do banco de dados, com migrações - pronto para uso
  • E um monte de pequenas mas agradáveis ​​coisinhas.

pesquisa de índice about.me
Parecia que o problema com o banco de dados estava completamente fechado. Estamos trabalhando! O caso foi debatido até chegarem à busca. Em vez disso, para pesquisa de texto completo. Mais precisamente, para pesquisar texto completo em russo, sem distinção entre maiúsculas e minúsculas. Ele não trabalhou. Absolutamente. Em inglês - trabalhou. A distinção entre maiúsculas e minúsculas também funcionou. Mas sem um registro, mas em russo - até chorar. Após pesquisar na ajuda, no rastreador de bugs e na Internet, verificou-se que, por algumas razões técnicas, era muito inconveniente para o desenvolvedor "pensar" em oferecer suporte a codificações multibyte e tudo o que vai além do alfabeto latino. Bem, ele não fez. Porque não

Nada a fazer, eu tive que procurar uma solução alternativa. Como resultado de um ataque breve, uma decisão "obstinada" foi tomada - criamos um campo separado "fulltext_index". Nele, duplicamos todo o texto em maiúsculas, "cortando" sinais de pontuação desnecessários, problemas desnecessários e todo tipo de lixo. Depois disso, é lógico supor que fazemos uma pesquisa com maiúsculas forçadas.

Vitória! A pesquisa agora funciona como um relógio em russo, mesmo em inglês!

Total: apesar dos problemas com o registro, o banco de dados funciona muito rápido, a conveniência é nivelada, um monte de chips prontos para uso - geralmente, eu recomendo.

Navegação no ecrã


O wix / react-native-navigation é um navegador simples e estável (um roteador, como diria um programador da web).

Foi escolhido apenas porque passou em todos os testes internos necessários (abertura da tela, pilha de chamadas, retorno, barra lateral). Em geral, o mínimo exigido mínimo.

controle deslizante do wix about.me
Diferente da amplamente utilizada navegação de reação , o wix tem 100% de natividade. Assim é - todas as transições entre telas são traduzidas para o código do aplicativo java e funcionam no nível do sistema.

No processo de desenvolvimento, eles encontraram um bug terrível da “tela branca” que ocorre apenas em alguns casos e em dispositivos individuais. Acontece que quando você sai do modo "suspensão", o processo de inicialização simplesmente congela. Depurador e depuração são silenciosos. No github sobre esse assunto, havia apenas dicas estranhas de "... tente jogar" com a ordem de carregar telas e outras graça bruxarias. Ainda não está claro em que nível o problema está oculto: o código java do Android ou já está na máquina JavaScript. Depois que dançamos com um pandeiro, o erro começou a aparecer com menos frequência, mas não desapareceu, permanecendo na lista de problemas não resolvidos. Infelizmente.

Excluindo esse "batente" - tudo é mais ou menos tolerável e suave. E, mais importante, nativo!

Sistema de arquivos


No sistema de arquivos, precisávamos armazenar fotos personalizadas, além de trabalhar com alguns arquivos relacionados ao backup. Como resultado da escolha entre duas opções possíveis, a opção caiu em react-native-fs
controle deslizante do wix about.me
"Acesso ao sistema de arquivos nativo" - está escrito na entrada do repositório. Bem, provavelmente é, mas com algumas alterações e limitações.

1. O acesso é apenas assíncrono. Como resultado, às vezes você precisa se lembrar de trabalhar com Promise / async / waitit. Embora em React, você comece a esquecê-lo.

A execução síncrona de uma função assíncrona (aguardar) exige que a função atual seja assíncrona (assíncrona). Para fazer isso, basta adicionar assíncrono na frente do nome da função. E sim, para o método da classe React.Component, isso também funciona. (na ajuda do React, o ReactNative não fala sobre isso, embora isso esteja implícito).

 export default class CloudIndex extends BasePage { async setupBackupFolders(init = false) { // some stuff there... await RunSomeAsyncFuncInSyncMode(foo, bar) RunFuncAfter(bar) } } 

É importante lembrar que, depois disso, a função também se torna assíncrona! Se já tiver sido usado em algum lugar antes, verifique novamente sua chamada.

2. O acesso completo a várias plataformas é apenas parte do sistema de arquivos. Essencialmente, apenas um diretório: DocumentDirectoryPath. E esse, de fato, é o diretório em que o aplicativo está. Esqueça a verificação do diretório raiz, a pesquisa de imagens na galeria, o áudio etc. Nada disso está disponível.

Mas, em geral, resolve suas tarefas 100%. No mastro do mealheiro hev.

Acesso à nuvem


A tarefa é simples e complexa. Simples, porque todo mundo tem uma API - pegue-a e use-a. É difícil - eu não quero ir mais fundo, e o formato da hora não me permitiu sentar e mexer nos métodos "possivelmente funcionais". Decidimos encontrar algo que funciona 100% e é implementado em uma extensão pronta para o React Native.

Havia exatamente um deles: Google Drive. O trabalho com o disco é compreensível e é orientado por solicitações banais da API. Mas obter acesso ao aplicativo no disco é uma história completamente diferente.
React-native-google-signin - sistema de gerenciamento de autorização do google .

controle deslizante do wix about.me
É aqui que "nos divertimos". Eles queriam mais simples e mais confiáveis, mas conseguiram ...

Tudo começou com a obtenção da chave do desenvolvedor. Anteriormente, o próprio Google fazia tudo isso. Mas após a aquisição do FireBase, decidiu-se transferir essa função para seu maravilhoso console.

Portanto, para obter a chave, você precisa:

  1. Registre o aplicativo no console do desenvolvedor do Google para "ativar" o acesso ao serviço do Drive.
  2. Registre o aplicativo no console do firebase.
  3. Crie um arquivo google-services.json no console do firebase - no qual as chaves de serviço estão protegidas.
  4. Coloque esse arquivo no projeto com a extensão instalada react-native-google-signin.

E então sim. Algo começa a funcionar. Em vez disso, os códigos de erro nas respostas de serviço começam a ser significativos.

É especialmente importante observar que a chave de API obtida pelo aplicativo diretamente ao conectar-se ao serviço não é eterna. Às vezes, muda uma vez por dia, às vezes uma vez por minuto. Portanto, antes de acessar o serviço, é sempre melhor verificar primeiro se a chave atual expirou. E se ele expirou - para receber novamente.

O processo de obtenção da chave de API do Google é o seguinte:

 await GoogleSignin.hasPlayServices() const userInfo = await GoogleSignin.signIn() this.setState({ userInfo: userInfo, }) settings.set('google.drive.key', userInfo.accessToken) trace('>> Key obtained:', userInfo.accessToken) this.apiKey = userInfo.accessToken 

Por exemplo, em nosso aplicativo, quando abrimos a tela de backup, tentamos obter pastas de backup com o ID do Google. Se tudo der certo, obtemos a identificação.

 backupRootID = await Storage.safeCreateFolder({ name: backupFolder, parents: ["root"], }).catch((e)=>{ if(e.status == 401) { trace(' >> Google signin unauthorized', e) signGoogle() return false } else { trace(' >> Google signin failed', e) } }) // Yeahh. The api key is valid, and rootID found on GoogleDrive! SomeStorage.setRootId(backupRootID) 

Caso contrário (erro 401, veio) - tentamos obter uma nova chave de API e repetimos a solicitação para obter o ID da pasta de backup novamente.

E mais algumas coisas agradáveis


Trabalhar com datas e horas


Momento de honra e louvor.js
O conhecimento desse milagre começou há muito tempo e foi muito bom que ele funcionasse tão bem no ambiente React Native.

Vários formatos, mágicos + - dia / mês / ano. Suporte para multilinguismo e formatos nacionais. Beleza!

Você pode tomar um banho com tomates, indicando que tudo isso é facilmente "controlado" por suas mãos com a Data usual, mas nas condições de rápido desenvolvimento NÃO pensar nessas coisas é muito, muito útil!

Gráficos e tabelas


controle deslizante do wix about.me
React-native-charts-wrapper - Wrapper JavaScript para MPAndroidCharts Android nativo.

Gostei da presença de uma abundância de vários tipos de gráficos (embora, neste estágio, tenhamos usado apenas dois deles - linear e “pie”).

Estragou a impressão por uma escassa referência de API quase ausente. O autor recomenda examinar a documentação dos MPAndroidCharts originais. De fato, o conselho acabou sendo difícil de implementar, uma vez que o último está sendo desenvolvido continuamente e supera a implementação do wrapper por várias versões. Além disso, o MPAndroidCharts é escrito em Java. Vrapper - em JavaScript. Você rapidamente tem que pensar no que é difícil.

Multilinguismo e traduções


controle deslizante do wix about.me
Reagir-nativo-i18n-trabalho como um encanto, pessoal!

Embora esse componente fique no github marcado como Preterido, ele funciona sem falhas e batentes. Todas as traduções estão espalhadas por arquivos com idiomas.

O uso dos parâmetros do tradutor também funciona com um estrondo:

 // en.js sync: { success: 'All items are up to date!', progress: 'Sync Notes %{idx} of %{total}' } //app.js import I18n from 'react-native-i18n' import en from './en.js' I18n.translations = { en } I18n.locale = "en" const _t = (msg, data) => { return I18n.t(msg, data) } console.log(_t('sync.progress', {idx: 3, total: 10})) 

No resíduo seco


O React Native atendeu a quase todas as suas expectativas. Com sua ajuda, você pode montar rapidamente um aplicativo de protótipo, trabalhar com a estrutura e a usabilidade. Todas as ferramentas necessárias para a "base" são.

Por outro lado, sempre existe o risco de ocorrer um "vácuo" quando simplesmente não há soluções prontas. Por exemplo, obtivemos isso ao enviar fotos para o aplicativo - um componente que normalmente pode cortar e beliscar imagens - apenas uma. E não foi iniciado em nossa compilação atual. Se a necessidade for muito "aguda" - você precisará atualizar quase metade do sistema, o que provavelmente levará a outra busca por erros.

Como nosso produto montado no React Native no mercado se mostrará, descobriremos nos próximos meses. Mas esta é uma história completamente diferente.

Source: https://habr.com/ru/post/pt430120/


All Articles