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
avecSpendingRepository
.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.