• 12 hours
  • Hard

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 3/22/24

Sauvegardez vos dépenses

Dans ce chapitre, nous allons utiliser notre entité Spending  pour sauvegarder les dépenses.

Supprimez la solution existante

Jusqu'à présent, le mécanisme qu'on utilisait pour sauvegarder les dépenses, c'était SpendingRepository. Cette classe utilisait le Singleton Pattern pour stocker les données dans un tableau spendings.

Bien sûr, maintenant on va utiliser Core Data, donc je vous invite à aller dans le fichier  SpendingRepository...

Sauvegardez la dépense

Les dépenses sont ajoutées dans l'interface AddSpendingViewController  lors de l'appui sur le bouton Save. Côté code, cela a lieu dans la méthode save  que voici :

@IBAction private func save() {
   guard
     let content = contentTextField.text,
     let amountText = amountTextField.text,
     let amount = Double(amountText)
   else { return }
   let spending = Spending(content: content, amount: amount)
   spendingRepository.add(spending: spending)
   navigationController?.popViewController(animated: true)
 }

Cette méthode fait trois choses :

  • Elle récupère les informations du formulaire.

  • Elle crée et sauvegarde un objet Spending  avec SpendingRepository.

  • Elle renvoie l'utilisateur vers la liste des dépenses.

Bien sûr, nous allons modifier la deuxième étape. Comme dans notre PeopleRepository, nous allons utiliser notre singleton du CoreDataStack  pour traiter les sauvegardes dans CoreData.

import Foundation

final class SpendingRepository {

  // MARK: - Properties

  private let coreDataStack: CoreDataStack

  // MARK: - Init

  init(coreDataStack: CoreDataStack = CoreDataStack.sharedInstance) {
    self.coreDataStack = coreDataStack
  }

  // MARK: - Repository

  func addSpending(with amount: Double, content: String, completion: () -> Void) {
    let spending = Spending(context: coreDataStack.viewContext)
    spending.amount = amount
    spending.content = content
    do {
      try coreDataStack.viewContext.save()
      completion()
    } catch {
      print("We were unable to save \(spending)")
    }
  }
}

À présent, nous avons encore une closure d'exécution disponible, que nous allons utiliser côté contrôleur :

// MARK: - Actions

  @IBAction private func save() {
   guard
    let content = contentTextField.text,
    let amountText = amountTextField.text,
    let amount = Double(amountText)
   else { return }
   spendingRepository.addSpending(
    with: amount,
    content: content,
    completion: { [weak self] in
      self?.navigationController?.popViewController(animated: true)
    })
  }

On voit ici que la méthode popViewController  est à présent appelée au moment de l'exécution de la closure. C'est-à-dire qu’elle est appelée lorsque notre repository appelle la méthode completion()  dans le bloc do-catch après avoir réussi à sauvegarder notre objet Spending.

Ajoutez la relation

Notre objet Spending  a une troisième propriété : person. Cette propriété fait le lien avec notre autre entité Person. Pour créer la relation, il nous suffit de donner à la propriété la personne choisie par l'utilisateur dans le Picker View.

On commence par mettre à jour notre méthode addSpending  dans notre SpendingsRepository  :

func addSpending(with amount: Double, content: String, for person: Person, completion: () -> Void) {
    let spending = Spending(context: coreDataStack.viewContext)
    spending.amount = amount
    spending.content = content
    spending.person = person
    do {
      try coreDataStack.viewContext.save()
      completion()
    } catch {
      print("We were unable to save \(spending)")
    }
 }

Puis, on va récupérer cette personne dans une méthode privée à part de notre AddSpendingViewController  :

private func getSelectedPerson() -> Person? {

    if !people.isEmpty {

       let index = personPickerView.selectedRow(inComponent: 0)
       return people[index]
    }
    return nil
 }

On la récupère dans notre tableau people  en utilisant l'index de la ligne sélectionnée par l'utilisateur dans le Picker View.

Ensuite, on va l'utiliser au moment de l’appel à notre repository pour la création de la dépense, et le code complet donne :

@IBAction private func save() {
   guard
    let content = contentTextField.text,
    let amountText = amountTextField.text,
    let amount = Double(amountText),
    let person = getSelectedPerson()
   else { return }
   spendingRepository.addSpending(
    with: amount,
    content: content,
    for: person,
    completion: { [weak self] in
     self?.navigationController?.popViewController(animated: true)
     })
 }

 private func getSelectedPerson() -> Person? {
   if !people.isEmpty {
       let index = personPickerView.selectedRow(inComponent: 0)
       return people[index]
   }
   return nil
 }

On utilise tout simplement la propriété person. On fait toujours de l'orienté objet classique !

Et voilà, notre dépense est sauvegardée dans Core Data ! Dans le prochain chapitre, nous allons récupérer nos données pour les afficher dans notre liste de dépenses.

Example of certificate of achievement
Example of certificate of achievement