Olá, boas-vindas, eu sou o Ândriu e esse é o curso de frameworks nativos para iOS, onde nós vamos dar continuidade a uma série de cursos que nós já estamos vendo sobre frameworks nativos. Nós temos aqui o app Alura Ponto, onde nós conseguimos registrar ponto.
Ou seja, o horário que um funcionário trabalha. Eu posso aqui registrar um ponto e eu tenho aqui os recibos com todos os horários que eu trabalhei.
A ideia desse curso é continuar as implementações, então nós vamos começar falando um pouco sobre armazenamento com o File Manager. No curso anterior, nós falamos um pouco sobre o core data, e agora nós vamos falar um pouco sobre o File Manager, como persistimos, por exemplo, essa foto de perfil local, utilizando o File Manager.
Depois nós vamos seguir com outro recurso bem interessante, que é a autenticação local, que também é nativa do iOS. No nosso caso, ao deletar um recibo - se eu clicar nesse "X", ele pede que eu faça a autenticação para conseguir apagar esse recibo. Esse recurso é muito utilizado em aplicativos de banco ou aplicativos que exigem uma identificação do usuário para fazer alguma ação, e vamos aprender através de deletar um recibo.
Depois nós vamos falar um pouco sobre localização, vamos aprender um pouco sobre core location, como podemos trackear a localização do usuário. E depois vamos falar também sobre o map kit, com o mapa da Apple. A ideia então é ao bater um ponto, registrarmos a latitude e longitude do usuário para conseguirmos exibir onde foi registrado o ponto. Então vamos trabalhar com o mapa do iOS.
Por último vamos falar um pouco sobre os quick actions, sobre o shortcut do iOS, então eu posso clicar e segurar e nós temos essa opção "Registrar ponto".
Nada mais é do que um atalho para o nosso aplicativo, então conseguimos também utilizar atalhos no nosso app de forma nativa. Esse é o conteúdo que nós vamos ver durante esse curso e eu espero você.
Estamos iniciando então mais um curso da nossa série de frameworks nativos para iOS. Então nós já iniciamos algumas implementações no primeiro curso, onde nós aprendemos a persistir informações com o core data, aprendemos a utilizar a câmera, a biblioteca de imagens. A ideia é continuarmos utilizando o mesmo projeto, que é Alura Ponto, um aplicativo para registrar o horário de trabalho do funcionário.
Então a hora que ele começa, a hora que vai almoçar, a hora que ele volta do almoço e a hora que ele termina de trabalhar. A ideia é registrar todos esses horários no aplicativo. No curso passado nós aprendemos então a persistir algumas coisas com o core data, quando nós batemos ponto nós já temos essas informações salvas, local, e temos aqui uma imagem de perfil que ainda nós não tratamos desse caso.
Quando eu clico para escolher uma foto, por exemplo, na verdade, é a foto de perfil do usuário, se eu fechar o aplicativo e rodar ele de novo, nós perdemos essa informação. Clico para ir para o perfil, eu não tenho mais a imagem.
Isso foi proposital, porque vamos utilizar outra maneira de trabalhar com persistência local no iOS, que é o File Manager, o gerenciador de arquivos. Nós aprendemos a trabalhar com o core data, nós temos também o File Manager, temos outras bibliotecas, como o user defaults para preferências do usuário, enfim, mas com certeza o File Manager também é muito utilizado para persistir esporadicamente algum arquivo que você precise.
Alguns cuidados que nós devemos ter é em relação ao tamanho dos arquivos que nós estamos armazenando com o File Manager, então fotos muito pesadas, em grande quantidade, se você precisar fazer algumas consultas mais rápidas no aplicativo, então é melhor você trabalhar com o core data ao invés do File Manager, porque ele é muito mais seguro e as consultas também são muito mais rápidas.
Mas, o File Manager, é muito importante termos esse conhecimento, porque quando você precisar persistir, esporadicamente, alguma coisa, você pode optar por esse recurso também. Então vamos lá, o que vamos começar a fazer? Vamos começar a trabalhar com o File Manager, o nosso gerenciador de arquivos, e vamos entender como salvar e como ler essa imagem através do File Manager.
Para começar, nós temos a nossa pasta "Model", onde nós temos já algumas classes: "Camera", "Recibo", "FormatadorDeData". Vamos criar um novo arquivo, botão direito em cima da pasta, novo arquivo, eu vou manter a opção "Swift File" mesmo, vou dar um "Next" e eu vou criar a classe chamada "Perfil". Vou dar um "Create". Vou criar aqui a classe.
class Perfil {}
. Nós vamos ter aqui um método chamado func salvarImagem()
, onde nós vamos receber, por parâmetro, a ( imagem: )
, nós selecionamos da biblioteca de imagens do iOS. Ela é um ( imagem: UIIMage) {}
. Nós não temos acesso às coisas do UIkit, porque estamos com o foundation.
Quando eu importo o UIkit automaticamente eu importo também o foundation, então agora eu posso utilizar o UIImage
que nós precisamos persistir. Eu vou começar criando uma constante, porque a ideia aqui, para conseguirmos salvar essa imagem, é acessarmos o diretório de pastas interno do nosso aplicativo.
Então todo aplicativo, quando nós buildamos ele no simulador, ele cria algumas pastas e podemos utilizar essas pastas para salvar os nossos arquivos. É como se criássemos uma pasta realmente aqui, no finder, eu tenho algumas pastas do curso. Quando eu abro, por exemplo, o terminal, se eu quiser entrar em alguma pasta, eu posso clicar e arrastar a pasta para o terminal e repare que eu tenho o endereço desta pasta.
Na "/Users/andriucoelho/Documents/alura-ponto-parte2", eu tenho aqui um path, um diretório. É esse diretório que precisamos acessar para conseguirmos criar a nossa pasta e salvar as coisas dentro. Vamos lá, vou fechar aqui. Eu vou criar uma constante chamada let diretorio =
, ela é igual ao = FileManager.default.urls()
.
Eu vou pegar esse primeiro método mesmo, onde nós precisamos apontar algumas configurações. A primeira é o tipo que eu quero acessar, o tipo da pasta que eu quero acessar. Eu quero acessar a pasta de documentos, então é (for: .documentDirectory,
. Esse in, na verdade, também é o tipo de pasta de permissão que eu quero acessar, então é esse in: .userDomainMask)
.
Ele retorna uma lista, então vou pegar a primeira dessa lista, ).first
, o primeiro path. Isso, na verdade, ele ficou opcional, repare que ele é uma URL opcional, só para desembrulhar essa linha com segurança, vou utilizar aqui o guard let
, se ele não conseguir, eu dou um .first else {return}
aqui no final.
Próximo passo, precisamos colocar um nome para essa foto que vamos salvar, let nomeDaFoto = " "
, que você pode colocar qualquer coisa, eu vou colocar "perfil.png"
. Depois disso, o que precisamos fazer? Precisamos montar a URL, repare que temos o endereço da pasta, mas precisamos concatenar com o nome da foto.
É isso que vamos fazer, pegar esse diretório, na verdade, uma barra, e perfil.png
. Como eu faço isso? Eu vou utilizar o appending path, só que eu vou criar uma constante, eu vou chamar de let urlDoArquivo =
. Eu vou utilizar aqui o diretório que eu criei e vou dar um = diretorio.appendingPathComponent()
e eu passo o (nomeDaFoto)
.
Já temos a nossa URL, com o diretório mais o nome da foto. Agora precisamos pegar essa imagem, que é um UIImage
, e precisamos converter isso para binário, porque não salvamos um UIImage
, nós salvamos os arquivos em bytes, e é isso que vamos fazer. Outra coisa que precisamos também fazer é uma verificação, para verificar se a foto já existe.
Por exemplo, se eu seleciono uma foto e depois eu quero trocar, eu preciso saber se essa foto já existe, para apagar antiga e salvar a nova foto. Vamos lá, como eu faço para verificar se já existe uma foto com esse nome? Eu vou utilizar também o File Manager, vou criar aqui uma verificação, if FileManager.default.
, eu vou utilizar esse .fileExists()
, onde eu passo o path.
O path eu já tenho, que é a URL do arquivo, ponto path, porque ele está esperando uma string, se eu passar só a URL do arquivo, ele é do tipo URL, por isso eu dou um path, (atPath: urlDoArquivo.path) {}
. Se isso for verdadeiro, ele cai aqui dentro desse if. O que eu vou fazer aqui?
Eu vou então remover a foto. //remover a foto
, já vamos ver como remover. Feita a verificação, depois disso eu posso então, de fato, salvar a minha imagem. Como eu salvo? Primeiro eu vou criar uma nova constante, que é, na verdade, a imagem, mas em outro formato, guard let imagemData =
- data não de data de dia, data de dados.
O que eu tentarei fazer aqui? Eu tentarei converter isso. Eu tenho um método que se chama = imagem.jpegData()
, onde eu passo, na verdade, de 0 a 1 qual a qualidade que eu quero salvar. Nesse caso, como é uma única foto, eu vou colocar (compressionQuality: 1) else
. Se eu não conseguir fazer essa conversão, eu também dou um else {return}
.
Com a imagem aqui, agora sim, eu vou utilizar o método onde vamos salvar, que é o seguinte, eu vou pegar a imagem e eu vou chamar esse método do { imagemData.write(to: )} catch {}
, onde eu passo uma URL, ou seja, eu vou escrever, eu vou salvar, eu vou persistir isso em algum lugar. Qual é o lugar?
Nós já temos a URL do arquivo, então vou passar aqui (to: urlDoArquivo)
. Caso eu não consiga, eu precisarei saber qual foi o erro. EU vou dar um try imagemData
, porque é uma throw function. Se não der certo, vamos verificar o que aconteceu.
Então nós já temos aqui um método onde nós estamos salvando a nossa imagem. Relembrando, primeiro precisamos do acesso ao local onde será salva essa foto, depois nós precisamos de fato criar o nome de uma foto e concatenar essa URL. E precisamos verificar se essa foto já existe, se já existir, apagamos a antiga e salvamos a nova.
Se não existir vamos então salvar a imagem. Agora precisamos ver como vamos remover a foto, e vamos ver isso no próximo vídeo.
Continuando, então faltou removermos a foto, caso ela exista. Para não ficar muito misturado, porque, na verdade, esse método é para salvar a imagem e não para remover, eu vou criar aqui um método que será especificamente para remover uma foto. private func removerImagemAntiga()
e eu vou pegar aqui, vou pedir para o parâmetro a URL em forma de string, ( url: String) {}
.
Dessa maneira nós não colocamos aqui a implementação de remover. Vamos passar então a URL, que é a URL do arquivo, removerImagemAntiga(urlDoArquivo.path)
, para ele retornar como string, porque só URL do arquivo é do tipo URL. Nós precisamos dela como string, por isso o .path
.
Aqui embaixo, nós vamos, na verdade, utilizar o FileManager.default.remove
, e temos dois métodos parecidos, um é at e o outro é at path. Como nós estamos trabalhando com string, vamos utilizar esse (atPath: url)
e vamos passar a URL. Ele vai reclamar aqui porque esse método .removeItem(atPath
é uma throw function, ou seja, é um método que pode disparar uma exceção.
Todos os métodos que tem essa assinatura do throw function, nós precisamos fazer uma verificação, na verdade, e tratar isso, porque pode ser que ele devolva um erro e nós podemos manipular esse erro. A maneira mais feia e perigosa de se trabalhar é colocar o try! FileManager
forçado e deixar o método assim.
Isso é ruim, porque pode ser que ele dispare um erro e o seu aplicativo vai dar crash e você não vai saber o que está acontecendo. Então evite trabalhar dessa forma. Nós vamos trabalhar dessa outra, que é mais segura, utilizando o do, catch, aqui é catch let error e vamos colocar todo esse código no do. Então ele vai tentar fazer esse comando, se ele não conseguir, ele vai estourar o erro e podemos verificar qual foi o erro.
No seu projeto, se você quiser, você pode colocar, por exemplo, um UI alert controller para mostrar uma mensagem para o usuário, caso dispare algum erro, vai da forma que você quer tratar os erros no seu app. Já temos aqui o removerImagemAntiga
, já estamos chamando ele no código.
Agora o que precisamos fazer, de fato, é chamar esse método salvarImagem
. Nós vamos no "ReciboViewController", aqui tem o método de delegate da câmera, que ele dispara ao escolher uma foto, que é esse método didSelectFoto
.
Então quando eu seleciono uma foto da biblioteca, ele cai aqui dentro desse código. O que vamos fazer aqui? Eu vou chamar a classe que nós criamos, que é classe Perfil().
, e eu vou chamar esse método ().salvarImagem(image)
, onde eu passo a imagem que eu selecionei na biblioteca.
Agora já podemos testar. Qual é o teste que eu vou fazer? Primeiro vamos verificar se a imagem realmente está sendo salva. Porém, como nós ainda não implementamos o método para recuperar essa imagem, nós só estamos salvando, só vamos colocar alguns breakpoints no nosso código.
Breakpoint nada mais é do que um ponto onde o nosso programa vai parar a execução e conseguimos inspecionar o valor de algumas variáveis, ver se ele entra no if ou no else, nós conseguimos ver, de fato, o que está acontecendo. Então primeiro eu vou colocar um breakpoint na linha 18, onde ele vai verificar se a imagem existe.
Eu vou colocar um outro breakpoint na linha 32, para ver se essa tentativa de remover a imagem está dando certo ou se está caindo no erro. A mesma coisa na linha 24, eu vou verificar se ele está conseguindo salvar a imagem ou se está estourando algum erro. Quando eu rodar o programa vai ficar um pouco mais fácil de entender o porquê desses breakpoints, você verá que eles são bem úteis para debug.
No app, cliquei em "Recibos", cliquei onde selecionamos a foto de perfil, biblioteca de fotos, vou escolher a cachoeira, "Escolher". Olha só, o programa parou na linha 18, repare que tem uma linha verde.
É exatamente no meu breakpoint, então breakpoint nada mais é do que essa figura azul, onde nós clicamos e ele para o nosso código. O que eu posso fazer agora? Eu vou remover toda essa mensagem para conseguirmos ver o valor de uma variável, caso precisemos, mas o mais importante são esses botões aqui embaixo.
No símbolo de play eu solto a execução, então ele parou, se eu clicar nesse ícone ele vai continuar a execução e cair no próximo breakpoint, se houver. Esse próximo botão, esse step over, ele vai para a linha debaixo. No botão que é uma seta para baixo, ele entra no método para verificar o valor das variáveis.
Nós vamos utilizar agora o step over, que é essa seta, o quarto botão. O que eu vou fazer? Eu vou verificar se ele vai entrar nessa linha 19 ou se ele já vai para a linha 22. Cliquei no step over, ele já foi para a linha 22, significa que ainda não existe nenhuma foto antiga, nós ainda não salvamos nenhuma foto.
Vou clicar mais uma vez para ir para a linha debaixo e aqui é onde nos interessa, a linha 25, ele vai tentar escrever, ele vai tentar salvar essa foto. Se essa linha verde vier para a linha 27, ou seja, se ele cair nesse print(error)
, significa que ocorreu algum erro, então fizemos alguma coisa errada.
Se ele não passar por aqui, significa que a foto está salva. Eu vou mais uma vez clicar nesse botão do step over e ele não entrou na linha 27, ele já veio direto para baixo.
Isso é muito bom. Porém, se eu vier no simulador, repare que a execução está toda travada, não consigo clicar em lugar nenhum, porque o meu breakpoint ainda está ativo. Como eu continuo a execução do meu programa? Através desse botão de play, "Continue program execution".
Clico nesse botão, ele vai soltar todos os breakpoints. É bem importante, porque às vezes você coloca um breakpoint, ele fica preso e você não sabe como continua a execução. Legal, já estamos salvando a imagem, já está funcionando.
Para finalizar então vou remover esses breakpoints. Como eu removo? Eu clico nele, seguro e arrasto para fora, clico e arrasto para direita em todos. Nós já asseguramos que a imagem está sendo salva. A seguir vamos implementar o método para recuperar essa imagem e setar no nosso outlet.
O curso IOS: autenticação, GPS e mais recursos nativos possui 135 minutos de vídeos, em um total de 35 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:
Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.
Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.
Emitimos certificados para atestar que você finalizou nossos cursos e formações.
Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.
Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.
Emitimos certificados para atestar que você finalizou nossos cursos e formações.
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com Luri até 100 mensagens por semana.
Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.
Acesso completo
durante 1 ano
Estude 24h/dia
onde e quando quiser
Novos cursos
todas as semanas