Começando com os dados principais! Difícil em palavras simples [Parte 2]

Neste artigo, gostaria de revelar ainda mais os recursos do Core Data. Este artigo é uma continuação . Eu realmente espero ter a ideia de que o Core Data não é um dos muitos bancos de dados relacionais, mas uma ferramenta muito poderosa que pode se tornar uma arma integral no arsenal de qualquer desenvolvedor de IOS que se preze.

Bem, vamos começar!

Hoje, trabalhamos com dois NSManageObjectContext e NSFetchedResultsController.

Dois NSManageObjectContext e por que isso é necessário?


Se seu aplicativo usa ativamente qualquer API através da qual recebe dados e você deseja salvá-los em algum lugar, o Core Data é uma excelente opção. Que problemas você pode ter com isso? A primeira e mais óbvia - a quantidade de dados será tão grande que, quando você tentar salvá-los, nosso aplicativo congelará por algum tempo, o que afetará a experiência do usuário. Um GCD comum não pode ser dispensado, pois é independente. Nossa Core Data Stack, mencionada aqui , funciona de forma síncrona e, para qualquer acesso ao nosso NSManageObjectContext, precisamos aguardar até o final do loop.

Mas aqui o NSManageObjectContext particular que funciona no encadeamento em segundo plano vem ao resgate. Para chamá-lo, você deve primeiro entrar em contato com o NSPersistentContainer.

A inicialização ficará assim:

lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "Preset")
    container.loadPersistentStores { (persistent, error) in
        if let error = error {
            fatalError("Error: " + error.localizedDescription)
        }
    }
    container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
    container.viewContext.shouldDeleteInaccessibleFaults = true
    container.viewContext.automaticallyMergesChangesFromParent = true
    return container
}()

Mergepolicy


Aqui você especifica a política de mesclagem do nosso NSManageObjectContext. Aqui, indicamos explicitamente como os Dados Principais devem se comportar no caso de um conflito de dados.

Opções MergePolicy:

  1. NSRollbackMergePolicy - No caso de um conflito, descarta todas as alterações até que ocorra.
  2. NSOverwriteMergePolicy - Salva novos valores, independentemente dos dados
  3. NSMergeByPropertyStoreTrumpMergePolicy - Salva a propriedade de objetos alterados por propriedade. Nesse caso, os dados salvos prevalecerão
  4. NSMergeByPropertyObjectTrumpMergePolicy - Salva a propriedade de objetos alterados por propriedade. Nesse caso, novos dados prevalecerão

AutomaticamenteMergesChangesFromParent - diz se nosso contexto mesclará dados automaticamente.Em
seguida, crie um novo contexto:

let context = persistentContainer.viewContext
let context = persistentContainer.newBackgroundContext()

Agora temos dois NSManageObjectContext. O primeiro é para trabalhar com a interface do usuário e é executado no encadeamento principal, e o segundo possui privateQueueConcurrencyType para trabalhar em segundo plano.

Vamos usá-lo para baixar dados.

let object = NSEntityDescription.insertNewObject(forEntityName: "Name", into: context)
saveChanges(with: context)

Aqui, criamos nossa Entidade e, em seguida, podemos atribuir as propriedades necessárias a ela; após o que chamamos o método save, fica assim:

func saveChanges(with context: NSManagedObjectContext) {
        context.performAndWait {
            if context.hasChanges {
                do {
                    try context.save()
                } catch {
                    context.rollback()
                }
            }
            context.reset()
        }
    }

Existem 2 métodos para escolher:

  • performAndWait - executa ações no encadeamento de contexto de forma síncrona
  • perform - executa ações no fluxo de contexto de forma assíncrona


NSFetchedResultsController


NSFetchedResultsController - um controlador que executa determinadas solicitações e exibe os dados necessários para o usuário.

lazy var fetchedResultsController: NSFetchedResultsController<Pack> = {
        let fetchRequest = NSFetchRequest<Pack>(entityName:"Pack")
        fetchRequest.fetchBatchSize = 20
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending:true)]
        let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

        controller.delegate = self
        do {
            try controller.performFetch()
        } catch {
            print(error.localizedDescription)
        }
        return controller
    }()

O NSFetchedResultsController possui um número muito grande de configurações. Vamos analisar algumas delas:

Fetchlimit
FetchLimit —

Sketchoffset
FetchOffset — . 2, .

FetchbatchSize
FetchBatchSize — . Table/CollectionView 5 , 7 , .

FetchbatchSize
FetchBatchSize — .

SortDescriptor
SortDescriptor — , .

ReturnsObjectsAsFaults
ReturnsObjectsAsFaults — , , , PersistentStore RawCache

No momento, temos um NSFetchedResultsController que deve exibir nossos dados em uma tabela. Para atualizar os dados, você precisa chamar o método delegate:

extension ViewController: NSFetchedResultsControllerDelegate {
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
       collectionView.reloadData()
    }
}

Este método delegado funciona quando temos alguma alteração em nosso contexto. Nesta implementação, isso acontece depois que salvamos os dados em um privateContext. Nesse momento, o método delegado é acionado e os dados são atualizados.

Apenas algumas ações e o Core Data de um banco de dados regular se transformam em uma arma poderosa para qualquer desenvolvedor iOS.

Feliz codificação!

All Articles