Aprendendo CoreData com SwiftUI

Neste mini-tutorial, passarei a você um pouco do que aprendi implementando o Core Data em um projeto CRUD com swiftUI no meu Nano Challenge Advanced Persistence. 🚀

Brevemente explicando, segundo a documentação da Apple, o Core Data é um framework usado para persistir e gerenciar objetos/dados de modelo em sua aplicação. Além de manipulá-los, ele salva dados permanentes do seu aplicativo para uso offline dentre outras características.

No meu projeto do Nano Challenge decidi que talvez fosse uma boa oportunidade para além de cumprir os requisitos solicitados de persistência, eu iria aprender SwiftUI.

Como o Core Data implementa a persistência? 🤔

Os dados geralmente são primeiramente adicionados dentro do contexto e são persistidos quando é adicionado o comando de save() dentro do contexto. Se você modifica no contexto ele fica salvo naquele contexto, só não é persistido se você não der um save(). Os arquivos são persistidos dentro de uma NSPersistentStore através de um NSPersistentStoreCoordinator.

Começando o projeto 🚀

Crie um projeto no Xcode, nas opções de criação do projeto, marque o Core Data, não esqueça de selecionar interface como SwiftUI, já que o nosso projeto não é UIKit.

Posteriormente eu mudei o nome do projeto para TodoList, então por favor, não se incomode com isso.

Não entraremos muito em estruturas do SwiftUI nesse tutorial, pois há tutoriais na web realmente focados nisso, inclusive a documentação oficial da Apple tem excelentes explicativos de como começar. Como você já deve saber, a nossaContentViewé semelhante a View da ViewController.swiftque é criado por padrão quando você inicia um novo projeto Xcode.

Em geral, inicializamos a função Core Data no SceneDelegate.swiftque possibilita-nos a execução de funções CRUD no container contido, mas como criamos o projeto com Core Data, essa função está sendo implementada como padrão, não haverá necessidade de configurarmos nada no SceneDelegate.swift nem no AppDelegate.swift, então, vamos partir.

Quando iniciamos o nosso projeto com Core Data, foi criado um arquivo chamado TodoList.xcdatamodeld, ele será usado para criar as entidades e relacionamentos (também pode ser adicionado posteriormente criando um arquivo do tipo Data Model caso não tenha criado o projeto com o CoreData). Clique em Add Entity(1) e adicione os atributos da entidade do nosso projeto. Em entities renomeio para o nome da nossa entidade(2), depois clique em Codegen(3) e coloque para Manual/None, em Module clique na "setinha" que marcará Current Product Module(4), depois disso adicione os atributos da tabela e tipo.

Exemplo

Crie uma pasta/grupo chamado Model, clique em Editor > Create NSManagedObject Subclass, ele vai criar os modelos do seu projeto, ,você pode fazer isso manualmente ou gerando como explicado, ambas as subclasses representam os atributos e relacionamentos, não entraremos em detalhes mas você pode conferir mais detalhadamente na documentação clicando aqui.

Exemplo de como criar uma NSManagedObject Subclass

Adicionamos um atributo de id: UUID que será usado como um identificador único para cada lembrete e remember: String que serão os lembretes da nossa to-do.
Agora vamos importar o Core Data na nossa ContentView e adicionar um Environment(\.managedObjectContext) var context antes da variável body, aqui estaremos passando uma instância do Core Data para o nosso projeto. O NSManagedObjectContext monitora as mudanças nas instancias dos tipos presentes (quando uma mudança ocorrer, ele que toma de conta). Adicione também logo abaixo do environment State private var taskReminder:String= "" e troque o Text por TextField("Task Name", text:$taskReminder . A notação State é um tipo de wrapper que possibilita observar mudanças no valor, ou seja, quando o valor do estado muda, a ele recalcula o corpo da view.

Seu código deve ficar assim:

Exemplo

Agora adicionaremos uma NavigationView ao nosso código, dentro dela adicionaremos também um Form e com duas Sections, a primeira conterá um textfield, e a segunda conterá os nossos lembretes, pois quando criarmos um lembrete ele aparecerá na lista. Após isso adicionaremos um navigationTitle e um navigationBarItems com um button. Para testar o button, você pode adicionar temporariamente um print.

A partir daqui, já podemos fazer a implementação no Core Data, também iremos fazer algumas modificações no nosso código.

Introdução ao Core Data Stack 🗄

O core data stack é composto de um ou mais contextos de objetos gerenciados conectados a um único PersistentStoreCoordinator que, por sua vez, está conectado a um ou mais armazenamentos persistentes. Uma Stack contém todos os componentes do Core Data de que você precisa para buscar, criar e manipular objetos gerenciados. No mínimo, ele contém:

Representação CoredataStack — Vinicius Mesquita Academy IFCE

Criaremos um State do tipo array de ToDoList para guardar os items do tipo ToDoList do CoreData, e ele receberá inicialmente um array vazio. Posteriormente carregaremos os dados do CoreData nele dentro do escopo do onAppear da NavigationView (o OnAppear é análogo ao viewDidAppear no UiKit). Ficará assim: State private var taskReminder:[ToDoList]= [] . Agora vamos definir a ação do botão plus que será responsável por adicionar um novo item no CoreData e criar uma variável que recebe o viewContext, assim:

Antes do final da nossa ContentView, iremos fazer um onAppear, que conterá uma variável que armazenará um fetchRequest, o onAppear irá rodar o código dentro dela assim que a tela recarregar.

No final fiz algumas mudanças no código, adicionei algumas pequenas funcionalidades, como:

1. onDelete para deletar uma tarefa da lista;

2. emptyState para mostrar uma mensagem quando não houver tarefas.

O projeto completo está aqui para você conferir.

Se você tiver algum problema com o projeto, ou tiver algo errado a reportar, não hesite em me contatar. Telegram: heyalley

--

--