Olá, gostaria de dar as boas-vindas a você que está iniciando mais um curso de IOS na Alura.
Audiodescrição: Ândriu Coelho é um homem branco de olhos castanhos e cabelo castanho-claro. Tem barba e bigode e usa uma camiseta azul-escura com o logotipo da Alura. Ao fundo, estúdio com iluminação gradiente do rosa para o azul. À direita, uma estante com decorações.
A ideia desse curso é continuar o desenvolvimento do aplicativo Vollmed, onde podemos procurar por especialistas e agendar uma consulta. Agora, vamos utilizar outro tópico, que é o tratamento de erros. O objetivo é pensar em casos de uso com caminhos alternativos.
Até então, estávamos focados no happy path (caminho feliz), mas sabemos que um aplicativo pode enfrentar instabilidade, ter problemas de conexão, e ocorrer vários tipos de erro no dia a dia. Nós, como pessoas desenvolvedoras, devemos saber tratar esses erros.
Vamos começar o curso configurando o Apiary, uma ferramenta em que podemos mockar (simular) uma resposta do back-end. Começaremos falando sobre status code, mais especificamente sobre erro 400. Vamos forçar um erro 400 utilizando o Apiary para verificar como o aplicativo se comporta.
Com base nisso, vamos avançar construindo um Snackbar de erro.
Snackbar de erro é uma view que podemos utilizar para diferentes situações dentro do aplicativo, incluindo mostrar um erro. Podemos mostrar uma view com uma mensagem para a pessoa usuária entender o que está acontecendo. É muito importante manter a pessoa usuária sempre informada.
Feito isso, partiremos para outro tópico importante em nosso curso, que é o Skeleton. Quando abrimos o aplicativo e aparece uma view de carregamento, chamamos de Skeleton.
O aplicativo pode demorar para trazer informações, e é importante manter a pessoa usuária sabendo do que está acontecendo, mostrando que o aplicativo está tentando carregar as informações.
Como pré-requisito, é importante que você tenha conhecimento em SwiftUI, ou que tenha feito os cursos da nossa formação sobre SwiftUI na Alura.
Esperamos que você tenha gostado dos tópicos que aprenderemos durante o curso. Até a primeira aula!
Para iniciar nosso curso, vamos dar continuidade ao Vollmed, um aplicativo onde conseguimos procurar por especialistas, como médicos, e agendar consultas.
Este projeto foi desenvolvido no decorrer dos cursos anteriores dessa formação. Se você não acompanhou o passo a passo, pode voltar nos cursos anteriores para verificar como foi desenvolvido.
Até então, trabalhamos primariamente com o happy path (caminho feliz). No entanto, sabemos que um aplicativo pode se tornar instável, porque não depende apenas dele. Fazemos requisições para servidores, dependemos de conexão com a internet, portanto, há vários problemas que podem acontecer.
A ideia neste curso é começar a trabalhar esses cenários. Daremos ênfase na importância de fornecer feedback para a pessoa usuária sobre o que está acontecendo no aplicativo.
Provavelmente, você já deve ter tido a experiência de usar algum aplicativo em que a tela travamos ou não entendeu o que estava acontecendo. Naquela ocasião, o problema poderia ter sido um erro não tratado ou internet lenta. Em todas essas situações, é importante manter a pessoa usuária informado sobre o que está acontecendo.
No curso em que falamos brevemente sobre o padrão arquitetural, começamos a mencionar sobre erros, mas não exploramos a fundo. No arquivo RequestError
que temos em "Vollmed > Networking > Base", já mapeamos alguns casos de erro.
RequestError.swift
:
enum RequestError: Error {
case decode
case invalidURL
case noResponse
case unauthorized
case unknown
case custom(error: [String: Any]?)
var customMessage: String {
switch self {
case .decode:
return "erro de decodificação"
case .unauthorized:
return "sessão expirada"
default:
return "erro desconhecido"
}
}
}
Portanto, temos casos de erros como decodificação, URL inválida , sem resposta, não autorizado e erro desconhecido. Apesar de mapear alguns dos possíveis erros, não mostramos para a pessoa usuária o problema que está ocorrendo. Neste curso, vamos prosseguir a partir disso.
Para começar, falaremos sobre alguns status codes mais conhecidos.
No menu lateral esquerdo, abrimos o arquivo HTTPClient
também dentro da pasta "Base". Nele, temos um switch/case
que valida o de acordo com o statusCode
.
HTTPClient.swift
:
switch response.statusCode {
case 200...299:
guard let responseModel = responseModel else {
return .success(nil)
}
guard let decodedResponse = try? JSONDecoder().decode(responseModel, from: data) else {
return .failure(.decode)
}
return .success(decodedResponse)
case 400:
let errorResponse = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
return .failure(.custom(error: errorResponse))
case 401:
return .failure(.unauthorized)
default:
return .failure(.unknown)
}
Relembrando, o status code é um código, geralmente de três dígitos, que o back-end retorna para o client (no nosso caso, o aplicativo), informando o que aconteceu em uma requisição.
Os status codes da classe 200
a 299
geralmente indicam sucesso. Nesse arquivo já temos um caso de erro mapeado, que é o 401
, quando não é autorizado, ou seja, quando tentamos fazer uma requisição e o token da pessoa usuária está inválido ou algo similar. Com base nesse status code, podemos tratar alguns erros.
Neste curso, vamos utilizar uma ferramenta chamada Apiary. Esta ferramenta é utilizada para documentar APIs e para simular (mock) a resposta de uma API.
É muito utilizada em equipes de desenvolvimento mobile, porque muitas vezes começamos a implementação e a equipe de back-end ainda não concluiu todo o desenvolvimento. Assim, conseguimos simular algumas respostas para consumir no front-end, no nosso caso, no nosso aplicativo.
Para começar, vamos abrir o navegador e procurar pela Apiary. Vamos acessar o primeiro link, que é a página oficial do Apiary. Para acessar a ferramenta, é necessário ter uma conta no GitHub.
Como já estamos logados na nossa conta, podemos clicar em "Continue" no canto superior direito para redirecionar a um projeto com um template padrão.
Vamos criar um novo projeto. Portanto, na barra superior esquerda, onde temos o nome da conta logada, vamos clicar no botão para expandir as opções. Em seguida, vamos clicar no botão verde "Create New API Project" para criar uma nova API. Com isso, podemos dar um nome para o projeto. Vamos nomeá-lo voll-med-api-erros
e clicar em "Create API".
Depois de clicar, ele traz as configurações do Apiary à esquerda e algumas informações sobre o projeto à direita.
Modelo padrão das configurações do Apiary
# voll-med-api-erros
Polls is a simple API allowing consumers to view polls and vote in them.
## Questions Collection [/questions]
### List All Questions [GET]
+ Response 200 (application/json)
[
{
"question": "Favamosrite programming language?",
"published_at": "2015-08-05T08:40:51.6202",
"choices": [
{
"choice": "Swift",
"votes": 2048
},
{
"choice": "Python",
"votes": 1024
},
{
"choice": "Objective-C",
"votes": 512
},
{
"choice": "Ruby",
"votes": 256
}
]
}
]
### Create a New Question [POST]
(restante omitido…)
Podemos configurá-lo de várias maneiras, mas vamos começar simulando um erro no caso de agendar uma consulta com uma pessoa especialista. Ou seja, quando fazemos um GET
para médicos especialistas. Por exemplo, vamos simular um erro clássico que pode acontecer, o erro 400.
Como fazemos para simular esse erro? No lado esquerdo do painel do Apiary, temos uma Response
com o status code 200
. Vamos alterar para 400
. Portanto, vamos criar um mock que simula um erro 400 no nosso servidor.
Em List All Questions
, configuramos o verbo da requisição, que continuará como GET
.
E em Questions Collection
é a rota da nossa API. Nesse caso, está a /questions
, porque é um padrão que ele já traz. Mas vamos mudar para /specialists
que significa especialista em inglês, conforme adotamos no projeto.
## Questions Collection [/specialists]
### List All Questions [GET]
+ Responde 400 (application/json)
Assim, quando se fizer um /specialists
, ele retornará um erro 400. E, logo abaixo, podemos configurar um JSON de erro. Isso, geralmente, é acordado com a equipe de back-end, que define qual será o JSON de erro que eles vão enviar. Você pode inseri-lo nesse espaço para simular este comportamento.
Dica: ao usar a Apiary é importante manter dois "Tabs" de distância para configurar o código corretamente.
Vamos criar um JSON de erro. Após dois "Tabs", abrimos chaves para começar a criar um objeto de erro. Portanto, digitamos error
entre aspas, seguido de dois-pontos e chaves.
Dentro destas chaves, vamos criar um objeto de erro. Primeiro, vamos enviar o código. Para isso, escrevemos code
como 400
, que é o status code de erro.
Também enviaremos uma mensagem, usando message
. Poderíamos colocar qualquer mensagem. Nesse caso, vamos usar uma mensagem padrão para começar os nossos estudos. Entre aspas, escrevemos Ops! Ocorreu um erro, mas já estamos trabalhando para solucionar
. Essa é a mensagem de erro inicial com a qual vamos trabalhar.
+ Responde 400 (application/json)
{
"error": {
"code": 400,
"message": "Ops! Ocorreu um erro, mas já estamos trabalhando para solucionar",
}
}
Em Create a New Question
, temos o POST
que não vamos utilizar. Portanto, podemos apagar desde esse título na linha 21 em diante.
Na linha 6, após o título principal voll-med-api-erros
, temos uma breve descrição do que faz o endpoint /specialists
. Vamos substituir a descrição padrão por Service used to simulate an error in the request
. Ou seja, um serviço utilizado para simular um erro em uma requisição.
# voll-med-api-erros
Service used to simulate an error in the request
Portanto, a primeira etapa será a configuração do Apiary para simular um erro na resposta do servidor.
Na lateral direita, em "List All Questions", a ideia é substituir o endpoint que ele nos fornece e usar no nosso aplicativo. No dropdown de "Request", vamos trocar "Production" por "Mock Server" (servidor simulado). Com isso, o seguinte endpoint é fornecido:
https://private-854ce4-vollmedapierros.apiary-mock.com/specialists
Para iniciar, queíamos configurar o Apiary com você, explicar o que exploraremos na primeira etapa deste curso. No próximo vídeo, vamos começar a trabalhar no projeto para entender como configurar o projeto para tratar esses casos de erro.
Até o próximo vídeo.
Com o Apiary configurado, podemos utilizá-lo no nosso projeto. A ideia, na parte direita da tela, onde ele nos fornece o endpoint de mock que criamos no API, é que ele retorne, de fato, esse JSON que configuramos.
https://private-854ce4-vollmedapierros.apiary-mock.com/specialists
Copiamos toda essa URL, abrir uma nova aba no navegador e colar no campo de endereço na parte superior. Teclamos "Enter" para buscar o endereço.
The resource you're looking for doesn't exist.
Please check the API documentation or have a look on available resources below.
Ele está informando que o recurso ainda não existe, então é importante salvar todas as alterações que fizermos. Voltando ao editor de código, selecionamos o botão "Save", localizado do lado superior direito. Atualizamos a página no navegador novamente.
{
"error": {
"code": 400,
"message": "Ops! Ocorreu um erro, mas já estamos trabalhando para solucionar"
}
}
Note que ele já nos retorna o JSON que configuramos no API. É exatamente isso que o aplicativo vai ler na hora de acessar o endpoint de mock que criamos utilizando o API.
Agora podemos voltar ao projeto no Xcode.
Para conseguirmos configurar essa URL no nosso projeto, devemos abrir o arquivo HTTPClient.swift
.
Do lado esquerdo do Xcode, temos a pasta Base
, que está dentro de Networking
, e abrimos o arquivo HTTPClient.swift .
Este arquivo contém a configuração dos endpoints que criamos no projeto. Para utilizar o que criamos na API, será necessário comentar todo esse bloco de código. Portanto, desde a linha 17 até a linha 21, vamos selecionar e apertar a tecla "Command + /" para comentar todas as linhas ao mesmo tempo.
HTTPClient.swift
// código omitido
extension HTTPClient {
func sendRequest<T: Decodable>(endpoint: Endpoint, responseModel: T.Type?) async -> Result<T?, RequestError> {
// var urlComponents = URLComponents()
// urlComponents.scheme = endpoint.scheme
// urlComponents.host = endpoint.host
// urlComponents.path = endpoint.path
// urlComponents.port = 3000
guard let url = urlComponents.url else {
return .failure(.invalidURL)
}
// código omitido
Podemos criar uma URL fake de Apiary semelhante àquela que configuramos na plataforma do Apiary. Copiamos o nome dessa constante que criamos na linha 23 e na linha 25 vamos substituir esse urlComponents.url
pela nova. Na verdade, como ela não é opcional, podemos até criar uma URL diferente. Não precisamos fazer essa verificação. Portanto, vamos voltar para como estava e comentamos da linha 25 à linha 27.
HTTPClient.swift
// código omitido
// var urlComponents = URLComponents()
// urlComponents.scheme = endpoint.scheme
// urlComponents.host = endpoint.host
// urlComponents.path = endpoint.path
// urlComponents.port = 3000
let urlApiary = URL "https://private-854ce4-vollmedapierros.apiary-mock.com/specialists"
// guard let url = urlComponents.url else {
// return .failure(.invalidURL)
// }
// código omitido
Vamos criar uma nova URL. Na linha 29, let url
é igual a URL()
. Vamos instanciar usando um inicializador com string. E passamos a URL. Copiamos a linha 23 e colamos na linha 29, onde podemos apagar a linha 23 (let urlApiary = URL "https://private-854ce4-vollmedapierros.apiary-mock.com/specialists"
).
HTTPClient.swift
// código omitido
// var urlComponents = URLComponents()
// urlComponents.scheme = endpoint.scheme
// urlComponents.host = endpoint.host
// urlComponents.path = endpoint.path
// urlComponents.port = 3000
// guard let url = urlComponents.url else {
// return .failure(.invalidURL)
// }
let url = URL(string:
"https://private-854ce4-vollmedapierros.apiary-mock.com/specialists")
// código omitido
Agora, podemos retornar uma URL opcional. Como, por exemplo, se digitarmos "fsdafdsfsdfsa" não é uma URL. Então, não conseguiremos criar esse objeto. Por ser opcional, podemos utilizar um guard
. E caso não consigamos, retornaremos uma falha usando o else{}
.
HTTPClient.swift
// código omitido
guard let url = URL(string: "https://private-854ce4-vollmedapierros.apiary-mock.com/specialists") else {
return .failure(.invalidURL)
}
// código omitido
Já temos uma URL para acessar o mock que criamos na API. Rodamos o aplicativo para testar, na parte superior esquerda, clicamos em "Run". E veremos o que acontece.
Ele está subindo o simulador do projeto e ao finalizar o carregamento, obtemos:
Isso é importante para também pensarmos nos caminhos alternativos do nosso projeto. Quando ele consegue recuperar os especialistas disponíveis é exibido uma lista e o aplicativo fica conforme o esperado
Porém, quando ele não consegue obter essas informações, fica uma tela branca abaixo da mensagem "Veja abaixo os especialistas de "Vollmed" disponíveis e marque sua consulta". Mas a pessoa usuária tentará visualizar e não terá sucesso, então devemos também pensar nos caminhos alternativos.
Nesse caso, estamos simulando um erro 400
. Para tratarmos desse erro, vamos abrir novamente o arquivo onde estamos mapeando o erro. Temos o enum
de erro, no arquivo RequestError .
RequestError
// código omitido
enum RequestError: Error {
case decode
case invalidURL
case noResponse
case unauthorized
case unknown
// código omitido
E no arquivo HTTPClient.swift
, temos o switch case
, onde estamos tratando o erro de acordo com o statusCode
, na linha 46.
400
A ideia é criar um novo case para a classe de erro 400. Então, na linha 59, temos esse retorno do sucesso. Vamos inserir um novo código e digitamos o caso de erro 400. Se der erro 400, vamos fazer alguma coisa com esse erro.
Primeiro, precisamos tentar recuperar a mensagem de erro que o servidor devolve. Para tal, criamos uma constante chamada errorResponse
.
Voltando ao navegador onde obtivemos o JSON, precisamos conseguir acessar a mensagem que o servidor nos devolve de alguma forma, e conseguimos fazer isso fazendo a decodificação da resposta.
Ops! Ocorreu um erro, mas já estamos trabalhando para solucionar
Voltamos ao Xcode.
Para acessarmos essa mensagem, usamos o JSONSerialization
, que é uma try function, então precisamos usar try?
.
Na linha 59, chamamos JSONSerialization.jsonObject()
passando o data
, que são os dados que o servidor nos devolve. Converteremos isso para um dicionário de [string:Any]
, ou seja, a chave do dicionário é uma string e o valor não tem um tipo definido.
Para visualizarmos no console, vamos usar um print()
de errorResponse
. Por enquanto, vamos retornar um caso de falha, mas vamos alterar isso depois. Vamos usar invalidURL
para conseguir buildar o projeto.
HTTPClient.swift
// código omitido
case 400:
let errorResponse = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
print(errorResponse)
return.failure(.invalidURL)
// código omitido
Vamos colocar um breakpoint, ou seja, um aviso que colocamos no código para a execução parar em determinado ponto, para que possamos inspecionar o valor da nossa variável. Na linha 59, clicamos acima do número "59" do lado esquerdo. Observem que agora temos uma flecha na cor roxa acima do número, indicando que o código será interrompido nesse ponto.
Compilamos o projeto novamente clicando no botão de play na parte superior esquerda para visualizarmos se conseguiremos ler a mensagem de erro ou não.
Quando a linha fica verde, significa que o código está parado nesse ponto onde configuramos. Na parte inferior direita, digitamos uma linha de comando para conseguirmos ler o valor desse erro, mas ele precisa passar por essa linha primeiro.
No canto inferior esquerdo, selecionamos o segundo ícone de step over (uma base com uma seta acima). Do lado direito, digitamos po print(errorResponse)
.
Por algum motivo, ele não está deixando imprimir o valor, mas como colocamos um print
na linha 60, faremos um step over e podemos visualizar se ele exibe o valor ali.
Obtemos:
Optional (["error": {
code = 400;
message = "Ops! Ocorreu um erro, mas já estamos trabalhando para solucionar"; }])
Do lado direito é exibido o error, o status code que é o 400, e a mensagem, que é exatamente o que configuramos aqui no API. Então, estamos conseguindo capturar essas informações no nosso aplicativo, exatamente isso que estamos lendo.
Como fazemos para continuar a execução do programa? Seguramos a linha 59 e arrastamos para fora e clicamos em continuar a execução do programa no primeiro ícone no canto inferior esquerdo.
Então o objetivo desse vídeo foi usarmos o mock que criamos no API para conseguirmos capturar a mensagem de erro. Agora nós temos um material, que é essa mensagem de erro, para informar ao usuário o que está acontecendo em nosso aplicativo.
Vamos continuar com isso a seguir!
O curso SwiftUI: identificando erros em suas requisições possui 96 minutos de vídeos, em um total de 36 atividades. Gostou? Conheça nossos outros cursos de iOS em Mobile, ou leia nossos artigos de Mobile.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.