Conteúdo Programático

Este documento apresenta o roteiro completo de tudo que será estudado ao longo da disciplina Sistemas Móveis. Ele foi pensado para que você, estudante, tenha desde o primeiro dia uma visão clara do caminho que percorrerá: de onde partiremos, por onde passaremos e onde chegaremos ao final do semestre. Leia este conteúdo programático com calma, pois ele vai orientar suas expectativas, ajudá-lo a se planejar e mostrar como cada tema se conecta ao seguinte, formando um percurso de aprendizagem coeso e progressivo.

A disciplina está organizada em 15 módulos temáticos, cada um correspondendo a uma semana de aulas. A lógica de progressão é simples: começamos pelos fundamentos da tecnologia e do ambiente de desenvolvimento, avançamos pelas técnicas de construção de interfaces, aprofundamos nos mecanismos de gerenciamento de estado e persistência de dados, integramos com serviços em nuvem, e concluímos com tópicos avançados de segurança, recursos nativos, internacionalização e qualidade de software. Cada módulo constrói sobre o anterior, de modo que o conhecimento se acumula de forma natural ao longo do semestre.

Ao final da disciplina, você terá desenvolvido, em equipe, uma aplicação móvel completa que integra todos os conceitos estudados. Este Projeto Integrador acompanha cada módulo, e a cada semana o grupo incorpora os novos conhecimentos ao produto que está construindo. Assim, aprender e fazer acontecem simultaneamente, o que é exatamente o espírito desta disciplina.

%%| label: linha-tempo-projeto
%%| fig-cap: Linha do Tempo do Projeto Integrador
%%| fig-width: 11
flowchart TD
    M01["Módulo 01<br/>Ambiente e Introdução"] --> M02["Módulo 02<br/>Linguagem Dart"]
    M02 --> M03["Módulo 03<br/>Widgets Fundamentais"]
    M03 --> M04["Módulo 04<br/>Layouts e Responsividade"]
    M04 --> M05["Módulo 05<br/>Navegação e Rotas"]
    M05 --> M06["Módulo 06<br/>Formulários e Validação"]
    M06 --> M07["Módulo 07<br/>Gerenciamento de Estado"]
    M07 --> M08["Módulo 08<br/>Persistência Local"]
    M08 --> M09["Módulo 09<br/>Consumo de APIs REST"]
    M09 --> M10["Módulo 10<br/>Backend AWS"]
    M10 --> EP["Entrega Parcial<br/>Módulo 10"]
    EP  --> M11["Módulo 11<br/>Autenticação e Segurança"]
    M11 --> M12["Módulo 12<br/>Notificações Push"]
    M12 --> M13["Módulo 13<br/>Recursos Nativos"]
    M13 --> M14["Módulo 14<br/>Internacionalização"]
    M14 --> M15["Módulo 15<br/>Testes e Publicação"]
    M15 --> EF["Entrega Final<br/>Projeto Integrador"]

    style EP fill:#fff3cd,stroke:#ffc107
    style EF fill:#d4edda,stroke:#28a745
    style M01 fill:#cfe2ff,stroke:#0d6efd
    style M02 fill:#cfe2ff,stroke:#0d6efd
    style M03 fill:#cfe2ff,stroke:#0d6efd
    style M04 fill:#d1ecf1,stroke:#17a2b8
    style M05 fill:#d1ecf1,stroke:#17a2b8
    style M06 fill:#d1ecf1,stroke:#17a2b8
    style M07 fill:#d1ecf1,stroke:#17a2b8
    style M08 fill:#fce8d5,stroke:#fd7e14
    style M09 fill:#fce8d5,stroke:#fd7e14
    style M10 fill:#fce8d5,stroke:#fd7e14
    style M11 fill:#f5c6cb,stroke:#dc3545
    style M12 fill:#f5c6cb,stroke:#dc3545
    style M13 fill:#e2d9f3,stroke:#6f42c1
    style M14 fill:#e2d9f3,stroke:#6f42c1
    style M15 fill:#d4edda,stroke:#28a745


Módulo 01 — Introdução ao Desenvolvimento Mobile e Configuração do Ambiente

Panorama geral e ponto de partida

O primeiro módulo é o seu ponto de entrada no universo do desenvolvimento mobile. Antes de escrever uma única linha de código, é importante entender por que as aplicações móveis se tornaram tão centrais na sociedade contemporânea e quais são as diferentes formas pelas quais elas podem ser construídas. Você compreenderá a distinção entre aplicações nativas, híbridas e multiplataforma, com atenção especial ao Flutter como a tecnologia adotada nesta disciplina.

Do ponto de vista técnico, este módulo é dedicado à configuração completa do ambiente de desenvolvimento no Windows 11. Você instalará o Flutter SDK, configurará o Android Studio junto com seus emuladores, integrará o Visual Studio Code com as extensões necessárias para o desenvolvimento Dart e Flutter, e inicializará seu primeiro repositório Git conectado ao GitHub. Ao final, você terá seu ambiente funcionando e executará um projeto Flutter simples, verificando que tudo está configurado corretamente.

A profundidade deste módulo é introdutória: o objetivo não é dominar Flutter neste primeiro contato, mas sim entender o ecossistema, ter o ambiente pronto e dar os primeiros passos com confiança. A configuração do ambiente, embora pareça uma tarefa mecânica, é um momento de aprendizagem importante: você começa a desenvolver a familiaridade com as ferramentas que usará durante todo o semestre.

Os temas centrais deste módulo compreendem a história e a evolução do desenvolvimento de aplicações móveis, desde os primeiros smartphones até o cenário atual; o comparativo entre abordagens nativas (Android com Kotlin/Java, iOS com Swift/Objective-C), híbridas (Ionic, Cordova) e multiplataforma (Flutter, React Native, Xamarin); a arquitetura interna do Flutter, incluindo o conceito de árvore de widgets, o motor de renderização e o modelo de compilação ahead-of-time que garante desempenho nativo; a instalação e configuração do Flutter SDK, Android Studio, emuladores Android e Visual Studio Code; os fundamentos do controle de versão com Git, incluindo inicialização de repositório, commits, branches e integração com o GitHub; e a criação e execução do primeiro projeto Flutter, explorando a estrutura de diretórios e arquivos gerada automaticamente pelo framework.


Módulo 02 — Fundamentos da Linguagem Dart

A linguagem que sustenta tudo

Antes de construir qualquer interface Flutter, é preciso compreender a linguagem Dart com solidez. Dart é uma linguagem moderna, fortemente tipada, desenvolvida pela Google, e possui um conjunto de características que a tornam especialmente adequada para o desenvolvimento de aplicações interativas e responsivas. Neste módulo, você estudará Dart com a profundidade necessária para o restante da disciplina, avançando além do básico e chegando aos recursos que tornam o código Flutter elegante e eficiente.

O aspecto mais importante que você aprenderá neste módulo é a programação assíncrona. Aplicações móveis precisam executar operações de longa duração, como requisições de rede e leitura de arquivos, sem bloquear a interface do usuário. Dart fornece mecanismos sofisticados para isso por meio de Futures, async/await e Streams. Compreender esses conceitos com clareza é indispensável para desenvolver aplicações Flutter que funcionem de maneira fluida.

Outro aspecto relevante é o sistema de null safety introduzido no Dart 2.12. Com null safety, o compilador Dart é capaz de garantir, em tempo de compilação, que variáveis não serão nulas quando não deveriam ser, eliminando uma categoria inteira de erros de tempo de execução que são comuns em outras linguagens. Você aprenderá a trabalhar com tipos anuláveis e não anuláveis de forma natural e produtiva.

Os temas deste módulo abrangem declaração e tipagem de variáveis com inferência de tipos e null safety; operadores aritméticos, relacionais, lógicos e de nulidade como ??, ?. e !; estruturas de controle de fluxo com if, else, switch, for, while e do-while; funções, parâmetros nomeados e opcionais, e arrow functions; closures e funções como objetos de primeira classe; classes, construtores, propriedades e métodos; herança, polimorfismo e mixins em Dart; interfaces implícitas e classes abstratas; generics e seu uso em coleções e funções; as principais coleções como List, Set, Map e seus métodos de transformação funcional como map, where e reduce; programação assíncrona com Future, async e await; Streams para sequências de eventos ao longo do tempo; e tratamento de exceções com try, catch, on e finally.

A profundidade de cobertura é intermediária a avançada para os tópicos de programação orientada a objetos, e avançada para programação assíncrona, dado que este último tema é extensamente utilizado nos módulos seguintes.


Módulo 03 — Widgets Fundamentais e Árvore de Widgets

Os blocos de construção de toda interface Flutter

No Flutter, tudo é um widget. Esta afirmação, frequentemente repetida, tem uma consequência prática profunda: para desenvolver qualquer interface, você precisa entender o que são widgets, como eles se organizam e como o Flutter os gerencia internamente. Neste módulo, você mergulhará no conceito de widget de forma detalhada, compreendendo a diferença entre StatelessWidget e StatefulWidget, e entendendo quando cada um deve ser utilizado.

A árvore de widgets é a estrutura central do Flutter. Cada elemento visual da tela é representado como um nó nessa árvore, e o Flutter percorre essa árvore para determinar o que deve ser desenhado na tela. Por baixo da árvore de widgets, o Flutter mantém duas outras árvores internas: a Element Tree e a Render Tree. Você não precisará manipular essas árvores diretamente, mas entender que elas existem e qual papel cada uma desempenha ajudará você a compreender por que o Flutter se comporta da maneira que se comporta, especialmente em situações de reconstrução de widgets.

O ciclo de vida do StatefulWidget é um tema que merece atenção especial. Métodos como initState, didChangeDependencies, build, didUpdateWidget e dispose têm momentos específicos em que são chamados, e usar cada um corretamente é fundamental para evitar vazamentos de memória e comportamentos inesperados na aplicação.

Os temas deste módulo incluem a filosofia de composição de widgets no Flutter e por que ela difere de outros frameworks de UI; os widgets estruturais como Scaffold, AppBar, Drawer, BottomNavigationBar e FloatingActionButton; os widgets de conteúdo como Text, Image, Icon, CircleAvatar e Divider; os widgets de entrada como TextField, Checkbox, Switch, Radio e Slider; a diferença entre StatelessWidget e StatefulWidget com exemplos práticos de quando usar cada um; o método setState e o mecanismo de reconstrução de widgets; o BuildContext e sua importância para acessar dados e temas da árvore ancestral; o uso de Keys e por que elas são necessárias para a reconciliação correta de listas dinâmicas de widgets; e o InheritedWidget como mecanismo nativo de propagação de dados pela árvore, base sobre a qual o Provider é construído.

A profundidade de cobertura é intermediária: você aprenderá não apenas a utilizar os widgets, mas a compreender o que acontece internamente quando eles são construídos, atualizados e destruídos.


Módulo 04 — Layouts e Responsividade

Organizando a interface para qualquer tamanho de tela

Uma aplicação bem construída precisa funcionar adequadamente em dispositivos de diferentes tamanhos, desde smartphones compactos até tablets com telas generosas. Neste módulo, você aprenderá as técnicas de organização visual que o Flutter oferece e como usá-las para criar interfaces que se adaptam ao espaço disponível de maneira elegante e funcional.

O sistema de layout do Flutter é baseado em um protocolo de constraints: cada widget pai informa ao widget filho quais são as dimensões mínimas e máximas que ele pode ocupar, e o filho decide seu tamanho dentro desses limites. Compreender esse protocolo é a chave para resolver os problemas de layout que inevitavelmente surgem durante o desenvolvimento. Muitos erros comuns, como o infame erro de “unbounded height”, têm origem exatamente na violação desse protocolo, e compreendê-lo permite resolvê-los com clareza.

Os widgets de layout linear, como Row e Column, são os mais utilizados no dia a dia. Mas o Flutter oferece muito mais: Stack para sobreposição de elementos, GridView para grades, ListView para listas roláveis, e os poderosos Slivers para efeitos de rolagem avançados. Você também aprenderá a utilizar MediaQuery e LayoutBuilder para criar interfaces genuinamente responsivas, que detectam o tamanho da tela e ajustam seu layout de forma inteligente.

Os temas deste módulo compreendem o protocolo de constraints do Flutter e como ele determina o tamanho de cada widget; os widgets Row e Column com todas as suas propriedades de alinhamento e distribuição de espaço, incluindo MainAxisAlignment, CrossAxisAlignment e MainAxisSize; os widgets Flexible e Expanded para distribuição proporcional de espaço em linhas e colunas; o widget Stack com Positioned e Align para sobreposição e posicionamento absoluto de elementos; os widgets de rolagem ListView, ListView.builder, GridView, GridView.builder e SingleChildScrollView; o widget Wrap para fluxo automático de elementos em múltiplas linhas; o MediaQuery para obtenção das dimensões da tela e orientação do dispositivo; o LayoutBuilder para construir layouts condicionais baseados no espaço disponível; o CustomScrollView com Slivers, incluindo SliverAppBar, SliverList e SliverGrid, para efeitos de rolagem avançados; e estratégias práticas para criar layouts adaptativos que funcionem bem em telefones e tablets.


Módulo 05 — Navegação e Roteamento

Conectando as telas da sua aplicação

Uma aplicação móvel raramente consiste em uma única tela. Na maioria dos casos, o usuário navega por diversas telas ao longo de sua interação com o aplicativo, e a forma como essa navegação é estruturada tem impacto direto tanto na experiência do usuário quanto na organização do código. Neste módulo, você aprenderá a implementar navegação de forma robusta e escalável utilizando o pacote go_router.

O Flutter oferece dois modelos de navegação: o Navigator 1.0, baseado em uma API imperativa que empurra e retira telas de uma pilha, e o Navigator 2.0, baseado em uma abordagem declarativa onde o estado da aplicação determina quais rotas estão ativas. O go_router é construído sobre o Navigator 2.0 e oferece uma API mais simples e intuitiva para definir rotas, passar parâmetros e implementar guards de autenticação.

Um conceito especialmente importante neste módulo é o de deep linking: a capacidade de navegar para uma tela específica da aplicação a partir de um link externo, como uma notificação push ou um link compartilhado. Você aprenderá como o go_router torna essa funcionalidade acessível e como integrá-la com outros sistemas que estudará mais adiante no semestre.

Os temas deste módulo abrangem os conceitos fundamentais de navegação em aplicações móveis e a metáfora da pilha de telas; o Navigator 1.0 com seus métodos push, pop, pushReplacement, pushAndRemoveUntil e a passagem de dados entre telas; as limitações do Navigator 1.0 que motivaram o desenvolvimento do Navigator 2.0; a configuração básica do go_router com definição de rotas e subrotas aninhadas; a navegação programática com context.go, context.push e context.pop; a passagem de parâmetros via path parameters e query parameters; os redirect do go_router para implementar guards de autenticação que redirecionam o usuário para a tela de login quando não está autenticado; o ShellRoute para manter elementos de navegação persistentes, como a barra de navegação inferior, enquanto o conteúdo central muda; a configuração de deep linking para Android; e as transições customizadas entre telas usando CustomTransitionPage.


Módulo 06 — Formulários, Validação e Feedback ao Usuário

Coletando dados com qualidade e clareza

Formulários são presentes em praticamente toda aplicação que coleta informações do usuário. Implementá-los corretamente vai muito além de colocar campos de texto na tela: é preciso validar as entradas, fornecer feedback claro quando algo está errado, gerenciar o foco entre campos e garantir uma experiência fluida ao usuário. Neste módulo, você aprenderá a construir formulários robustos com as ferramentas que o Flutter oferece.

O widget Form, combinado com TextFormField e o objeto FormState, fornece uma estrutura organizada para gerenciar a validação de múltiplos campos de forma coordenada. Você aprenderá a criar validadores síncronos para verificações imediatas, como formato de e-mail e comprimento de senha, e validadores assíncronos para verificações que requerem consulta ao servidor, como verificar se um nome de usuário já está em uso.

O feedback ao usuário durante o processamento de ações é outro tema central deste módulo. Quando o usuário toca em um botão de envio e a aplicação realiza uma operação demorada, é fundamental indicar visualmente que o sistema está trabalhando. O pacote loading_overlay oferece uma forma prática de implementar esse feedback. Além disso, você aprenderá a utilizar SnackBar, Dialog e BottomSheet para comunicar resultados e solicitar confirmações de maneira elegante.

Os temas deste módulo compreendem a estrutura de formulários com os widgets Form, FormState e TextFormField; o método validate() do FormState e como ele coordena a validação de todos os campos do formulário; a criação de validadores customizados para diferentes tipos de dado, como CPF, e-mail, telefone e campos obrigatórios; o gerenciamento de foco com FocusNode, incluindo o movimento automático de foco para o próximo campo quando o usuário pressiona a tecla de retorno; as propriedades do TextField relacionadas ao tipo de teclado (TextInputType) e à ação do botão de confirmação (TextInputAction); a formatação de entrada com TextInputFormatter para máscaras como datas e documentos; o pacote loading_overlay para exibir indicadores de carregamento durante operações assíncronas; o SnackBar para mensagens temporárias de feedback; os widgets AlertDialog e SimpleDialog para interações de confirmação; o BottomSheet e o showModalBottomSheet para painéis deslizantes de informação ou seleção; e boas práticas de experiência do usuário em formulários móveis, incluindo ordenação lógica dos campos e clareza nas mensagens de erro.


Módulo 07 — Gerenciamento de Estado com Provider

O coração da arquitetura Flutter

O gerenciamento de estado é um dos temas mais importantes e, ao mesmo tempo, mais desafiadores do desenvolvimento Flutter. Estado é qualquer dado que pode mudar ao longo do tempo e cujas mudanças precisam ser refletidas na interface do usuário. Quando uma aplicação é simples, gerenciar o estado com setState dentro de um único widget é suficiente. Mas à medida que a aplicação cresce, o estado precisa ser compartilhado entre múltiplas telas e componentes, e é aí que soluções como o Provider se tornam indispensáveis.

O Provider é um pacote que implementa o padrão de injeção de dependências e o padrão Observer de uma forma idiomática ao Flutter. Com ele, você pode definir classes de estado que notificam automaticamente os widgets dependentes quando seus dados mudam, eliminando a necessidade de passar dados manualmente por toda a árvore de widgets, um problema conhecido como “prop drilling”. Você aprenderá a criar ChangeNotifiers, a expô-los com ChangeNotifierProvider e a consumi-los eficientemente com Consumer e Selector.

O GetIt é outra ferramenta que você estudará neste módulo. Enquanto o Provider é excelente para gerenciar estado reativo na interface, o GetIt funciona como um service locator: um registro central onde você pode registrar instâncias de serviços, repositórios e outros objetos, e recuperá-los em qualquer parte do código sem precisar passá-los por construtores. A combinação de Provider e GetIt resulta em uma arquitetura limpa, testável e escalável.

Os temas deste módulo abrangem os diferentes tipos de estado em aplicações Flutter, com a distinção entre estado efêmero (local ao widget) e estado de aplicação (compartilhado globalmente); as limitações do gerenciamento de estado com setState em aplicações de maior complexidade; a arquitetura do pacote Provider e seus fundamentos no padrão InheritedWidget; a criação de classes ChangeNotifier para modelar o estado de domínio da aplicação; os widgets ChangeNotifierProvider, Consumer, Selector e context.watch/context.read e quando utilizar cada um; o MultiProvider para registrar múltiplos providers na raiz da aplicação; o ProxyProvider para criar providers que dependem de outros providers; o FutureProvider e o StreamProvider para integrar dados assíncronos com a árvore de widgets; a configuração e utilização do GetIt como service locator; padrões de arquitetura aplicados ao Flutter, com ênfase na separação entre a camada de apresentação e a camada de lógica de negócios; e as bases da arquitetura MVVM (Model-View-ViewModel) aplicada ao contexto Flutter com Provider.


Módulo 08 — Persistência Local de Dados

Guardando dados no dispositivo do usuário

Toda aplicação útil precisa guardar dados de alguma forma. Seja para lembrar as preferências do usuário entre sessões, manter um cache de dados baixados da internet para funcionamento offline, ou armazenar registros criados pelo próprio usuário, a persistência local é um recurso fundamental. Neste módulo, você aprenderá as diferentes opções de armazenamento local disponíveis no Flutter e como escolher e utilizar cada uma de acordo com o tipo de dado que precisa ser persistido.

O SharedPreferences é a solução mais simples: um armazenamento de chave-valor ideal para dados de configuração como preferências de tema, idioma selecionado ou token de sessão. Para dados estruturados e relacionais, o SQLite é a escolha adequada. Por meio do pacote sqflite, você aprenderá a criar tabelas, executar consultas SQL, realizar operações CRUD e gerenciar migrações de schema conforme a aplicação evolui.

O path_provider complementa essas soluções fornecendo acesso ao sistema de arquivos do dispositivo, permitindo que a aplicação salve e leia arquivos diretamente, o que é útil para armazenar imagens baixadas, documentos exportados ou logs de atividade.

Um aspecto especialmente valioso que você aprenderá é a estratégia de cache: como decidir quando usar dados armazenados localmente versus buscar dados atualizados do servidor, e como sincronizar os dois quando a conectividade é restabelecida após um período offline.

Os temas deste módulo incluem uma visão comparativa das opções de persistência local no Flutter, com os critérios de escolha entre cada abordagem; o SharedPreferences para leitura e escrita de dados primitivos de configuração; o pacote path_provider e os diretórios do dispositivo que uma aplicação pode acessar, como o diretório temporário e o diretório de documentos; a criação e gerenciamento de arquivos no sistema de arquivos do dispositivo; o SQLite como banco de dados relacional embutido e sua integração no Flutter via pacote sqflite; a abertura e criação de bancos de dados com openDatabase e a função onCreate; a definição de schema com criação de tabelas em SQL; as operações de inserção com insert, consulta com query e rawQuery, atualização com update e exclusão com delete; transações para garantir a atomicidade de múltiplas operações; migrações de schema com o parâmetro onUpgrade para evoluir o banco de dados sem perder dados do usuário; a modelagem de classes Dart que representam entidades do banco de dados, com métodos toMap e fromMap; e estratégias de cache para funcionamento offline e sincronização com backend remoto.


Módulo 09 — Consumo de APIs REST

Conectando a aplicação ao mundo externo

A maioria das aplicações móveis modernas não existe de forma isolada: ela se comunica com servidores para buscar dados, enviar informações, autenticar usuários e sincronizar o estado com outros dispositivos. A forma mais comum de fazer essa comunicação é por meio de APIs REST, e é exatamente isso que você aprenderá neste módulo.

O pacote http fornece os meios para realizar requisições HTTP em Dart de forma direta e controlada. Você aprenderá a construir requisições GET, POST, PUT, PATCH e DELETE, a enviar e receber dados no formato JSON, e a tratar os diferentes cenários de resposta do servidor, incluindo erros de autenticação, recursos não encontrados e falhas de rede.

A serialização e desserialização de JSON é um tema que merece atenção cuidadosa. Em Dart, os dados JSON chegam como objetos do tipo Map<String, dynamic>, e é sua responsabilidade converter esses mapas em instâncias de suas classes de modelo. Você aprenderá a criar factory constructors para esse propósito, estabelecendo uma convenção consistente que tornará seu código organizado e fácil de manter.

Um aspecto arquitetural importante deste módulo é o padrão Repository: ao invés de chamar a API diretamente dos widgets ou dos providers, você aprenderá a criar uma camada de repositório que abstrai a origem dos dados. Essa abstração torna o código mais testável e permite trocar a implementação da fonte de dados (por exemplo, substituindo a API por um banco local) sem alterar o restante da aplicação.

Os temas deste módulo abrangem os fundamentos do protocolo HTTP e do estilo arquitetural REST, incluindo métodos HTTP, códigos de status e o formato JSON; o pacote http e os métodos get, post, put, patch e delete; a construção de Uri para URLs com parâmetros de query; a serialização de objetos Dart para JSON com jsonEncode e a desserialização com jsonDecode; a criação de classes de modelo com construtores fromJson e métodos toJson; a definição de cabeçalhos HTTP customizados, incluindo o cabeçalho de autorização para APIs autenticadas; o tratamento de diferentes categorias de erro, como erros de rede, timeouts e erros de servidor; a exibição de estados de carregamento, dados carregados e erro na interface com base no estado da requisição; o padrão Repository para abstrair o acesso a dados remotos; a combinação de repositório local (SQLite) e repositório remoto (API REST) com uma camada de decisão de cache; e estratégias de retry automático para lidar com falhas transitórias de rede.


Módulo 10 — Integração com Backend AWS

Construindo e integrando um backend serverless — e marco da Entrega Parcial

Até o módulo anterior, você consumiu APIs de servidores externos. Neste módulo, você aprenderá a construir seu próprio backend na nuvem utilizando os serviços da Amazon Web Services. A arquitetura serverless que será estudada elimina a necessidade de gerenciar servidores físicos ou virtuais: você escreve funções que são executadas sob demanda, paga apenas pelo tempo de execução, e o próprio provedor de nuvem cuida de toda a infraestrutura de escalabilidade e disponibilidade.

O API Gateway é o ponto de entrada do backend: ele recebe as requisições HTTP provenientes da aplicação Flutter e as encaminha para as Lambda Functions correspondentes. Cada Lambda Function é um pedaço de código independente que executa uma tarefa específica, como buscar registros do banco de dados ou processar um pagamento. O RDS PostgreSQL fornece a camada de persistência relacional, enquanto o SQS permite o processamento assíncrono de tarefas que não precisam de resposta imediata.

Este módulo tem um caráter mais exploratório do que os anteriores, pois envolve tecnologias de cloud que podem ser novas para você. O objetivo não é torná-lo um especialista em AWS, mas sim capacitá-lo a configurar e utilizar esses serviços no contexto do Projeto Integrador, compreendendo os princípios de funcionamento de cada componente e as conexões entre eles.

Este módulo coincide com o marco da Entrega Parcial do Projeto Integrador, quando o grupo apresentará o trabalho desenvolvido até aqui.

Os temas deste módulo compreendem o modelo de computação serverless e suas vantagens em relação ao modelo tradicional de servidores; a criação e configuração de uma REST API no API Gateway da AWS, incluindo recursos, métodos e integrações; o desenvolvimento de Lambda Functions para processamento de requisições; a integração da Lambda Function com o RDS PostgreSQL para leitura e escrita de dados; a configuração de variáveis de ambiente nas Lambda Functions para armazenar configurações sensíveis como strings de conexão com o banco de dados; a definição de stages no API Gateway para ambientes de desenvolvimento e produção; a integração da aplicação Flutter com o API Gateway, reutilizando os conhecimentos do módulo de consumo de APIs REST; o Amazon SQS para enfileiramento de mensagens e processamento assíncrono de tarefas; o monitoramento de funções Lambda com AWS CloudWatch, incluindo visualização de logs de execução; e boas práticas de segurança na AWS, como o princípio de menor privilégio na definição de permissões IAM.


Módulo 11 — Autenticação e Segurança

Protegendo dados e garantindo identidade

Segurança é um aspecto que não pode ser tratado como opcional ou como algo a ser adicionado após a aplicação estar pronta. Ela precisa ser considerada desde o início do desenvolvimento, permeando todas as decisões de arquitetura. Neste módulo, você aprenderá os conceitos e as ferramentas necessárias para implementar autenticação robusta e proteger os dados sensíveis dos usuários de sua aplicação.

O OAuth 2.0 é o protocolo padrão da indústria para autorização, e você aprenderá a implementar o fluxo Authorization Code com PKCE, que é o fluxo recomendado para aplicações móveis. O pacote oauth2_client abstrai os detalhes do protocolo e simplifica a integração com provedores de identidade. Uma vez que o usuário esteja autenticado, os tokens de acesso precisam ser armazenados de forma segura, e para isso o flutter_secure_storage utiliza os mecanismos de armazenamento seguro nativos de cada plataforma: Keychain no iOS e EncryptedSharedPreferences no Android.

A autenticação biométrica, implementada com o pacote local_auth, adiciona uma camada adicional de conveniência e segurança: em vez de digitar uma senha a cada acesso, o usuário pode confirmar sua identidade com impressão digital ou reconhecimento facial. Você aprenderá a verificar se o dispositivo suporta biometria, a solicitar a autenticação e a integrar esse fluxo de forma natural na experiência do usuário.

Os temas deste módulo incluem os conceitos de autenticação, autorização e identidade, com as diferenças entre cada um; o protocolo OAuth 2.0 e seus diferentes fluxos (Authorization Code, Implicit, Client Credentials e Resource Owner Password), com ênfase no fluxo Authorization Code com PKCE para aplicações móveis; os tokens de acesso (Access Token) e tokens de atualização (Refresh Token), seus tempos de vida e o processo de renovação automática de sessão; a utilização do pacote oauth2_client para implementação do fluxo OAuth 2.0; o flutter_secure_storage para armazenamento seguro de tokens nos mecanismos nativos de cada plataforma; a implementação de interceptors na camada de serviços HTTP para adicionar automaticamente o token de autorização a cada requisição; o tratamento do código de status 401 (Unauthorized) para iniciar o processo de renovação do token ou redirecionar o usuário para o login; a autenticação biométrica com o pacote local_auth, incluindo verificação de suporte, listagem dos tipos de biometria disponíveis e solicitação de autenticação; e a proteção contra ameaças comuns em aplicações móveis, como armazenamento inseguro de dados, comunicação sem HTTPS e exposição de chaves de API no código-fonte.


Módulo 12 — Notificações Push com Firebase Cloud Messaging

Mantendo o usuário informado e engajado

Notificações push são uma das funcionalidades mais poderosas para manter os usuários de uma aplicação engajados e informados. Quando bem utilizadas, elas entregam informações relevantes no momento certo, aumentando o valor percebido da aplicação. Neste módulo, você aprenderá a implementar notificações push de ponta a ponta, desde a configuração do Firebase até o envio programático de notificações a partir de uma Lambda Function na AWS.

O Firebase Cloud Messaging é o serviço de mensageria da Google que funciona como intermediário entre o servidor que quer enviar uma notificação e o dispositivo do usuário que deve recebê-la. Cada dispositivo instalado com a aplicação recebe um token FCM único, que funciona como um endereço para o qual as notificações podem ser enviadas. Você aprenderá a obter e gerenciar esses tokens, a enviá-los ao backend para que o servidor possa usá-los posteriormente, e a implementar a lógica de recebimento de notificações nos diferentes estados em que a aplicação pode se encontrar.

Uma notificação pode chegar quando a aplicação está em primeiro plano (foreground), quando está em segundo plano (background) ou quando está completamente encerrada (terminated). Cada um desses estados requer um tratamento diferente, e você aprenderá como lidar com cada cenário, incluindo a navegação para uma tela específica quando o usuário toca em uma notificação.

Os temas deste módulo abrangem a arquitetura do sistema de notificações push e o papel do Firebase Cloud Messaging nela; a criação de um projeto no console Firebase e a configuração do aplicativo Flutter; a integração dos pacotes firebase_core e firebase_messaging no projeto Flutter; a inicialização do Firebase e a solicitação de permissão para enviar notificações ao usuário; a obtenção do token FCM do dispositivo e o envio desse token ao backend para armazenamento; a configuração do handler de mensagens em foreground com FirebaseMessaging.onMessage; a configuração do handler de mensagens em background e terminated com FirebaseMessaging.onBackgroundMessage; a manipulação do evento de toque na notificação com FirebaseMessaging.onMessageOpenedApp e getInitialMessage; a estrutura de uma mensagem FCM, incluindo notification (título e corpo exibidos na bandeja) e data (payload de dados para lógica interna da aplicação); o envio de notificações a partir de uma Lambda Function AWS utilizando o Firebase Admin SDK; e considerações sobre o respeito à privacidade e preferências de notificação do usuário.


Módulo 13 — Acesso a Recursos Nativos e Permissões

Usando os recursos do hardware do dispositivo

Os smartphones modernos são equipados com uma impressionante variedade de sensores e hardware: câmeras, GPS, acelerômetro, giroscópio, microfone, luz ambiente e muito mais. O Flutter, por sua natureza multiplataforma, fornece plugins que permitem acessar esses recursos de forma unificada, independentemente de o aplicativo estar rodando em Android ou iOS. Neste módulo, você aprenderá a acessar os recursos nativos mais úteis para o desenvolvimento de aplicações práticas.

O modelo de permissões dos sistemas operacionais móveis é a porta de entrada para acessar recursos sensíveis. Em versões recentes do Android e iOS, o usuário precisa conceder permissão explicitamente antes que a aplicação possa acessar câmera, localização ou microfone. O pacote permission_handler oferece uma API unificada para solicitar, verificar e responder ao status dessas permissões, levando em conta as diferenças entre as plataformas.

Você aprenderá boas práticas para a solicitação de permissões: quando solicitá-las (idealmente no momento em que o recurso é necessário, não na inicialização do aplicativo), como explicar ao usuário por que a permissão é necessária antes de solicitá-la, e como lidar graciosamente com a recusa, desativando a funcionalidade correspondente sem travar a aplicação.

Os temas deste módulo compreendem o modelo de permissões do Android e iOS e como ele evoluiu para proteger a privacidade do usuário; o ciclo de solicitação de permissões com o pacote permission_handler, incluindo os estados granted, denied, restricted e permanentlyDenied; as melhores práticas para solicitar permissões apenas quando necessário e com contexto claro ao usuário; o acesso à câmera do dispositivo para captura de fotos e vídeos; o acesso à galeria de imagens para seleção de arquivos pelo usuário; o serviço de geolocalização para obtenção da posição atual do dispositivo com precisão configurável; a atualização contínua de posição para rastreamento em tempo real; o acesso a sensores do dispositivo como acelerômetro e giroscópio por meio de streams de dados; e o compartilhamento de conteúdo com outras aplicações instaladas no dispositivo por meio do mecanismo de intents do Android e activities do iOS.


Módulo 14 — Internacionalização e Acessibilidade

Alcançando mais pessoas com mais qualidade

Uma aplicação bem construída é aquela que pode ser usada pelo maior número possível de pessoas, independentemente do idioma que falam ou das limitações físicas que possam ter. A internacionalização e a acessibilidade são dois temas relacionados a essa visão inclusiva do desenvolvimento de software. Neste módulo, você aprenderá as técnicas para preparar sua aplicação para audiências multilíngues e para usuários com diferentes necessidades de acessibilidade.

O pacote i18n_extension simplifica o processo de internacionalização em Flutter de uma forma muito mais prática do que as alternativas oficiais. Com ele, você anota strings diretamente no código com uma sintaxe intuitiva e organiza as traduções em arquivos separados por idioma. A troca de idioma acontece em tempo de execução, sem necessidade de reiniciar a aplicação, e o sistema cuida automaticamente da detecção do idioma do sistema operacional.

A acessibilidade em Flutter é centrada no widget Semantics, que permite adicionar informações descritivas a qualquer elemento da interface para que leitores de tela como TalkBack (Android) e VoiceOver (iOS) possam verbalizá-los corretamente. Construir uma interface acessível não requer um esforço extraordinário quando feito desde o início do desenvolvimento, mas requer consciência sobre as necessidades dos usuários que dependem dessas tecnologias assistivas.

Os temas deste módulo incluem os conceitos de internacionalização (i18n), localização (l10n) e globalização no contexto de aplicações móveis; a configuração do pacote i18n_extension e a estrutura de arquivos de tradução; a anotação de strings com o operador .i18n para marcar textos que precisam de tradução; a organização das traduções por idioma e a adição de novos idiomas ao projeto; a formatação de datas, horas, números e moedas de acordo com o locale do usuário, utilizando as funcionalidades da biblioteca intl; o suporte a idiomas com direção de texto da direita para a esquerda (RTL), como árabe e hebraico; a detecção automática do idioma do sistema operacional e a implementação de um seletor de idioma manual na interface; os fundamentos de acessibilidade e as diretrizes WCAG aplicadas ao contexto de aplicações móveis; o widget Semantics para adicionar descrições a elementos da interface que não possuem texto visível, como ícones e imagens; o teste de acessibilidade utilizando os recursos do próprio sistema operacional (TalkBack no Android, VoiceOver no iOS); e a adaptação de temas para alto contraste e suporte ao tamanho de fonte configurado pelo usuário no sistema operacional.


Módulo 15 — Testes, Qualidade e Publicação

Garantindo a qualidade e entregando a aplicação ao mundo

O módulo final da disciplina reúne dois temas que marcam a maturidade de um processo de desenvolvimento: a garantia de qualidade por meio de testes automatizados e a publicação da aplicação nas lojas oficiais. Esses temas são frequentemente negligenciados em projetos de aprendizagem, mas são indispensáveis no desenvolvimento profissional e constituem a diferença entre um protótipo e um produto.

O Flutter oferece um excelente suporte a três níveis de teste. Os testes unitários verificam a lógica de unidades individuais de código, como métodos de cálculo ou transformação de dados, de forma isolada e rápida. Os testes de widget verificam a aparência e o comportamento de componentes de interface de usuário em um ambiente simulado. Os testes de integração verificam o comportamento da aplicação completa em um dispositivo ou emulador real. Você aprenderá a escrever testes nos três níveis e a desenvolver a mentalidade de que testes são documentação viva do comportamento esperado do sistema.

A publicação de uma aplicação envolve etapas de preparação que vão além da compilação: geração de ícones e splash screens, configuração de permissões no manifesto do Android, assinatura do aplicativo com um keystore, e a submissão para revisão nas lojas. Você compreenderá o fluxo completo de publicação tanto na Google Play Store quanto na Apple App Store, e as diferenças no processo de revisão de cada plataforma.

Os temas deste módulo abrangem a filosofia de testes automatizados e o conceito de pirâmide de testes; a escrita de testes unitários com o pacote test para verificar lógica de negócios isolada de dependências externas; o uso de mocks com a biblioteca mockito para simular dependências em testes unitários; a escrita de testes de widget com o pacote flutter_test, utilizando WidgetTester para interagir com a interface de forma programática; os matchers do flutter_test para verificar a presença e o estado de widgets na tela; a escrita de testes de integração com integration_test que rodam em um dispositivo ou emulador real e validam fluxos completos da aplicação; a análise estática de código com flutter_lints para identificar problemas de código antes de executar a aplicação; a preparação de assets de publicação, incluindo ícones em todas as resoluções necessárias e splash screens; a geração de um build de release assinado para Android com a configuração do keystore; a geração de um build de release para iOS com os certificados e perfis de provisionamento necessários; o processo de criação de uma conta de desenvolvedor e a submissão do aplicativo na Google Play Store; e o processo correspondente na Apple App Store, incluindo o TestFlight para distribuição de versões de teste.


Visão Integrada: O Projeto Integrador como Fio Condutor

Ao longo de todos os 15 módulos, o Projeto Integrador funcionará como o fio que conecta cada tema ao seguinte. Desenvolvido em equipes de quatro ou cinco estudantes, o projeto consiste na criação de uma aplicação móvel completa utilizando Flutter, com backend integrado aos serviços AWS. Cada módulo contribui com um incremento concreto ao projeto: no Módulo 01, configura-se o ambiente e inicializa-se o repositório; no Módulo 02, escreve-se os primeiros modelos de domínio em Dart; no Módulo 03, constroem-se os primeiros widgets; e assim sucessivamente até o Módulo 15, quando o projeto é finalizado, testado e preparado para publicação.

Ao final do 10º módulo, ocorre a Entrega Parcial, quando cada equipe apresenta ao professor o progresso acumulado. Essa entrega representa 20% da nota final e é uma oportunidade para receber feedback e ajustar o rumo antes da reta final. A Entrega Final ocorre na semana seguinte ao término do 15º módulo e representa 40% da nota. O restante da avaliação, 40%, refere-se à participação e ao engajamento ao longo de todo o semestre.

%%| label: linha-tempo-projeto
%%| fig-cap: Linha do Tempo do Projeto Integrador
%%| fig-width: 11
gantt
    title Linha do Tempo do Projeto Integrador
    dateFormat  DD/MM
    axisFormat %d/%m
    tickInterval 1week
    weekday monday
    todayMarker stroke-width:2px,stroke:#0f0,opacity:0.5
    excludes 15/02, 16/02, 17/02, 18/02, 19/02, 20/02, 21/02, 03/04, 20/04, 21/04, 01/05, 04/06, 05/06

    section Fundamentos Flutter
    Inicio                        :milestone, inicio, 02/02, 1w
    Configuração e repositório    :m1, after inicio, 1w
    Modelos de domínio em Dart    :m2, after m1, 1w
    Primeiros widgets da interface :m3, after m2, 1w

    section Interface do Usuário
    Layouts das telas principais  :m4, after m3, 1w
    Navegação entre telas         :m5, after m4, 1w
    Formulários com validação     :m6, after m5, 1w

    section Arquitetura e Dados
    Estado global com Provider    :m7, after m6, 1w

    section Integração e Serviços
    Persistência local com SQLite :m8, after m7, 1w
    Consumo da API do backend     :m9, after m8, 10d
    Integração com AWS            :m10, after m9, 11d
    Entrega Parcial               :milestone, after m10, 0d

    section Recursos Avançados
    Autenticação OAuth2           :m11, after m10, 1w
    Notificações push             :m12, after m11, 1w
    Câmera e localização          :m13, after m12, 1w
    Internacionalização           :m14, after m13, 1w

    section Qualidade e Entrega
    Testes e build de release     :m15, after m14, 1w
    Entrega Final                 :milestone, after m15, 0d

Este conteúdo programático é um mapa, não um destino. À medida que você avançar pelos módulos, descobrirá conexões entre os temas que talvez não estejam explícitas aqui. A profundidade com que cada conceito se apresentará nas aulas e nos materiais de estudo vai muito além do que este documento pode antecipar. Use este roteiro para se orientar, planejar seu estudo e manter a perspectiva de onde cada tema se encaixa no quadro maior de sua formação como desenvolvedor de aplicações móveis.