Skip to content

Commit ec71f14

Browse files
authored
Merge pull request #18 from lauramarson/refactor/coredata
Refactor/coredata
2 parents 35e85cc + 566c14d commit ec71f14

6 files changed

Lines changed: 92 additions & 40 deletions

File tree

AnimalsApp/AnimalsApp/Services/CoreData.swift

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,34 @@ import UIKit
99
import CoreData
1010

1111
protocol CoreDataContract: AnyObject {
12+
var delegate: [UpdateDelegateProtocol] { get set }
13+
var favoriteAnimals: [FavoriteAnimal] { get set }
1214
func loadFavoriteAnimals(completion: @escaping () -> ())
1315
func isFavorite(id: String) -> Bool
1416
func addFavorite(_ animal: Animal)
1517
func removeFavorite(id: String)
1618
func saveChanges()
1719
}
1820

21+
protocol UpdateDelegateProtocol: AnyObject {
22+
func updateFavoriteAnimals()
23+
}
24+
1925
class CoreData: CoreDataContract {
20-
var managedContext: NSManagedObjectContext?
21-
static var favoriteAnimals = [FavoriteAnimal]() {
26+
static let shared = CoreData()
27+
28+
private var managedContext: NSManagedObjectContext?
29+
30+
var delegate = [UpdateDelegateProtocol]()
31+
var favoriteAnimals = [FavoriteAnimal]() {
2232
didSet {
23-
notifyChanges?()
33+
delegate.forEach { delegate in
34+
delegate.updateFavoriteAnimals()
35+
}
2436
}
2537
}
2638

27-
static var notifyChanges: (() -> Void)?
28-
29-
init() {
39+
private init() {
3040
managedContext = (UIApplication.shared.delegate as? AppDelegate)?
3141
.persistentContainer
3242
.viewContext
@@ -38,7 +48,7 @@ class CoreData: CoreDataContract {
3848
let fetchRequest: NSFetchRequest<FavoriteAnimal> = FavoriteAnimal.fetchRequest()
3949

4050
do {
41-
CoreData.favoriteAnimals = try managedContext.fetch(fetchRequest)
51+
self.favoriteAnimals = try managedContext.fetch(fetchRequest)
4252
completion()
4353
} catch let error as NSError {
4454
print("Could not fetch. \(error), \(error.userInfo)")
@@ -47,7 +57,7 @@ class CoreData: CoreDataContract {
4757

4858
func isFavorite(id: String) -> Bool {
4959

50-
for animal in CoreData.favoriteAnimals {
60+
for animal in self.favoriteAnimals {
5161
if animal.id == id {
5262
return true
5363
}
@@ -66,7 +76,7 @@ class CoreData: CoreDataContract {
6676
newFavoriteAnimal.descript = animal.description
6777
newFavoriteAnimal.age = Int32(animal.age ?? 0)
6878
newFavoriteAnimal.species = animal.species
69-
CoreData.favoriteAnimals.append(newFavoriteAnimal)
79+
self.favoriteAnimals.append(newFavoriteAnimal)
7080
}
7181

7282
func removeFavorite(id: String) {
@@ -75,10 +85,10 @@ class CoreData: CoreDataContract {
7585

7686
var count = 0
7787

78-
for animal in CoreData.favoriteAnimals {
88+
for animal in self.favoriteAnimals {
7989
if animal.id == id {
8090
let removeAnimal = animal
81-
CoreData.favoriteAnimals.remove(at: count)
91+
self.favoriteAnimals.remove(at: count)
8292
managedContext.delete(removeAnimal)
8393
}
8494
count += 1

AnimalsApp/AnimalsApp/View Models/FavoritesViewModel.swift

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,24 @@
88
import Foundation
99

1010
class FavoritesViewModel {
11+
let coreData: CoreDataContract
12+
1113
var favoriteAnimals = [Animal]()
14+
private var newCoreDataChanges = true
15+
16+
init(coreData: CoreDataContract = CoreData.shared) {
17+
self.coreData = coreData
18+
coreData.delegate.append(self)
19+
}
1220

1321
func getFavoriteAnimals(completion: @escaping () -> Void) {
14-
let coreDataAnimals = CoreData.favoriteAnimals
15-
favoriteAnimals.removeAll(keepingCapacity: true)
22+
guard newCoreDataChanges else { return }
1623

17-
coreDataAnimals.forEach { favoriteAnimal in
18-
let newAnimal = Animal(id: favoriteAnimal.id, name: favoriteAnimal.name, description: favoriteAnimal.descript, age: Int(favoriteAnimal.age), species: favoriteAnimal.species, isFavorite: true, imageData: favoriteAnimal.image)
19-
favoriteAnimals.append(newAnimal)
24+
favoriteAnimals = coreData.favoriteAnimals.map { favoriteAnimal in
25+
Animal(id: favoriteAnimal.id, name: favoriteAnimal.name, description: favoriteAnimal.descript, age: Int(favoriteAnimal.age), species: favoriteAnimal.species, isFavorite: true, imageData: favoriteAnimal.image)
2026
}
2127

28+
newCoreDataChanges = false
2229
completion()
2330
}
2431

@@ -29,4 +36,18 @@ class FavoritesViewModel {
2936
func modelAt(_ index: Int) -> Animal {
3037
return favoriteAnimals[index]
3138
}
39+
40+
func removeFavorite(at index: Int, completion: @escaping () -> Void) {
41+
guard let id = favoriteAnimals[index].id else { return }
42+
favoriteAnimals.remove(at: index)
43+
coreData.removeFavorite(id: id)
44+
completion()
45+
}
46+
}
47+
48+
extension FavoritesViewModel: UpdateDelegateProtocol {
49+
func updateFavoriteAnimals() {
50+
newCoreDataChanges = true
51+
}
52+
3253
}

AnimalsApp/AnimalsApp/View Models/HomeViewModel.swift

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ class HomeViewModel {
1212
private var coreData: CoreDataContract
1313
var animals = [Animal]()
1414

15-
init(webServices: WebServicesContract = WebServices(), coreData: CoreDataContract = CoreData()) {
15+
init(webServices: WebServicesContract = WebServices(), coreData: CoreDataContract = CoreData.shared) {
1616
self.webServices = webServices
1717
self.coreData = coreData
18+
coreData.delegate.append(self)
1819
}
1920

2021
func numberOfRows() -> Int {
@@ -58,14 +59,16 @@ class HomeViewModel {
5859
}
5960
}
6061

61-
func addOrRemoveFavorite(at index: Int, with image: Data) {
62+
func removeFavorite(at index: Int) {
63+
guard let id = animals[index].id else { return }
64+
coreData.removeFavorite(id: id)
65+
animals[index].isFavorite = false
66+
}
67+
68+
func addFavorite(at index: Int, with image: Data) {
6269
animals[index].imageData = image
63-
64-
guard let isFavorite = animals[index].isFavorite,
65-
let id = animals[index].id else { return }
66-
isFavorite ? coreData.removeFavorite(id: id) : coreData.addFavorite(animals[index])
67-
68-
animals[index].isFavorite = !isFavorite
70+
coreData.addFavorite(animals[index])
71+
animals[index].isFavorite = true
6972
}
7073

7174
func loadFavorites(completion: @escaping () -> ()) {
@@ -78,3 +81,9 @@ class HomeViewModel {
7881
coreData.saveChanges()
7982
}
8083
}
84+
85+
extension HomeViewModel: UpdateDelegateProtocol {
86+
func updateFavoriteAnimals() {
87+
// setFavorite()
88+
}
89+
}

AnimalsApp/AnimalsApp/Views/Components/AnimalTableViewCell.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import UIKit
99
import SDWebImage
1010

1111
protocol ActionDelegateProtocol: AnyObject {
12-
func favoriteButtonTapped(at index: Int, with image: Data)
12+
func addFavoriteTapped(at index: Int, with image: Data)
13+
func removeFavoriteTapped(at index: Int)
1314
}
1415

1516
class AnimalTableViewCell: UITableViewCell {
@@ -57,19 +58,18 @@ class AnimalTableViewCell: UITableViewCell {
5758
}
5859

5960
@IBAction func favoritePressed(_ sender: UIButton) {
60-
guard let animal = animal else { return }
61+
guard let animal = animal, let index = index else { return }
6162

6263
if animal.isFavorite ?? false {
6364
sender.setImage(.notFavorite, for: .normal)
6465
self.animal?.isFavorite = false
66+
delegate?.removeFavoriteTapped(at: index)
6567
} else {
6668
sender.setImage(.favorite, for: .normal)
6769
self.animal?.isFavorite = true
68-
}
69-
70-
if let index = index, let image = SDImageCache.shared.imageFromDiskCache(forKey: animal.imageURL.absoluteString) {
71-
let imageData = image.jpegData(compressionQuality: 0.9)
72-
delegate?.favoriteButtonTapped(at: index, with: imageData ?? Data())
70+
let image = SDImageCache.shared.imageFromDiskCache(forKey: animal.imageURL.absoluteString)
71+
let imageData = image?.jpegData(compressionQuality: 0.9)
72+
delegate?.addFavoriteTapped(at: index, with: imageData ?? Data())
7373
}
7474
}
7575
}

AnimalsApp/AnimalsApp/Views/FavoritesViewController/FavoritesViewController.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,27 @@ import UIKit
99

1010
class FavoritesViewController: UIViewController {
1111

12-
var favoritesVM = FavoritesViewModel()
12+
var favoritesVM: FavoritesViewModel?
1313

1414
@IBOutlet weak var tableView: UITableView!
1515

1616
override func viewDidLoad() {
1717
super.viewDidLoad()
18+
favoritesVM = FavoritesViewModel()
1819

1920
tableView.dataSource = self
2021
tableView.delegate = self
2122

2223
tableView.register(UINib(nibName: "AnimalTableViewCell", bundle: nil), forCellReuseIdentifier: "Animal")
2324

2425
setNavigationItems()
26+
favoritesVM?.getFavoriteAnimals { [weak self] in self?.tableView.reloadData()
27+
}
2528
}
2629

2730
override func viewWillAppear(_ animated: Bool) {
2831
super.viewWillAppear(animated)
29-
favoritesVM.getFavoriteAnimals() { [weak self] in self?.tableView.reloadData()
32+
favoritesVM?.getFavoriteAnimals { [weak self] in self?.tableView.reloadData()
3033
}
3134
}
3235

@@ -47,7 +50,7 @@ class FavoritesViewController: UIViewController {
4750
// MARK: TableView Data Source
4851
extension FavoritesViewController: UITableViewDataSource {
4952
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
50-
return favoritesVM.numberOfRows()
53+
return favoritesVM?.numberOfRows() ?? 0
5154
}
5255

5356
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -56,7 +59,7 @@ extension FavoritesViewController: UITableViewDataSource {
5659
return UITableViewCell()
5760
}
5861

59-
cell.animal = favoritesVM.modelAt(indexPath.row)
62+
cell.animal = favoritesVM?.modelAt(indexPath.row)
6063
cell.index = indexPath.row
6164
cell.delegate = self
6265
cell.configure()
@@ -83,8 +86,13 @@ extension FavoritesViewController: UITableViewDelegate {
8386

8487
// MARK: Action Delegate Protocol
8588
extension FavoritesViewController: ActionDelegateProtocol {
86-
func favoriteButtonTapped(at index: Int, with image: Data) {
87-
// homeVM.addOrRemoveFavorite(at: index, with: image)
89+
func addFavoriteTapped(at index: Int, with image: Data) {
90+
}
91+
92+
func removeFavoriteTapped(at index: Int) {
93+
favoritesVM?.removeFavorite(at: index) { [weak self] in
94+
self?.tableView.reloadData()
95+
}
8896
}
8997
}
9098

AnimalsApp/AnimalsApp/Views/HomeViewController/HomeViewController.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ extension HomeViewController: UITableViewDelegate {
124124

125125
// MARK: Action Delegate Protocol
126126
extension HomeViewController: ActionDelegateProtocol {
127-
func favoriteButtonTapped(at index: Int, with image: Data) {
128-
homeVM.addOrRemoveFavorite(at: index, with: image)
129-
}
127+
func addFavoriteTapped(at index: Int, with image: Data) {
128+
homeVM.addFavorite(at: index, with: image)
129+
}
130+
131+
func removeFavoriteTapped(at index: Int) {
132+
homeVM.removeFavorite(at: index)
133+
}
130134
}

0 commit comments

Comments
 (0)