Skip to content

Commit 35e85cc

Browse files
authored
Merge pull request #17 from lauramarson/favoritesView
Favorites viewcontroller
2 parents b348d91 + c2ec483 commit 35e85cc

6 files changed

Lines changed: 153 additions & 19 deletions

File tree

AnimalsApp/AnimalsApp.xcodeproj/project.pbxproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
56CADB59A535B3ED60380013 /* Pods_AnimalsApp_AnimalsAppUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E75A013A1B19FF9D2B114B /* Pods_AnimalsApp_AnimalsAppUITests.framework */; };
1212
5CA996F8285A98FB00FF5D79 /* RegisterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA996F7285A98FB00FF5D79 /* RegisterViewModel.swift */; };
1313
A2A6AE83CC0E1DAC784999B1 /* Pods_AnimalsAppTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 290D574622CE042567539136 /* Pods_AnimalsAppTests.framework */; };
14+
A458A086285E58CC0057BC34 /* FavoritesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A458A085285E58CC0057BC34 /* FavoritesViewModel.swift */; };
1415
A463D0172858EBBB00929A3C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A463D0162858EBBB00929A3C /* AppDelegate.swift */; };
1516
A463D0212858EBBB00929A3C /* AnimalsApp.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = A463D01F2858EBBB00929A3C /* AnimalsApp.xcdatamodeld */; };
1617
A463D0232858EBBD00929A3C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A463D0222858EBBD00929A3C /* Assets.xcassets */; };
@@ -35,8 +36,8 @@
3536
A463D071285A373800929A3C /* Animals.swift in Sources */ = {isa = PBXBuildFile; fileRef = A463D070285A373700929A3C /* Animals.swift */; };
3637
A463D074285A398900929A3C /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A463D073285A398900929A3C /* HomeViewModel.swift */; };
3738
A463D078285A5A8000929A3C /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A463D077285A5A8000929A3C /* OpenSans-Regular.ttf */; };
38-
A463D07C285B9B6300929A3C /* CoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A463D07B285B9B6300929A3C /* CoreData.swift */; };
3939
A463D07A285B8D8E00929A3C /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = A463D079285B8D8D00929A3C /* Colors.swift */; };
40+
A463D07C285B9B6300929A3C /* CoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A463D07B285B9B6300929A3C /* CoreData.swift */; };
4041
A463D07E285CF28200929A3C /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = A463D07D285CF28200929A3C /* String.swift */; };
4142
/* End PBXBuildFile section */
4243

@@ -68,6 +69,7 @@
6869
81C9DABDE310C2E15910D06C /* Pods-AnimalsAppTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AnimalsAppTests.debug.xcconfig"; path = "Target Support Files/Pods-AnimalsAppTests/Pods-AnimalsAppTests.debug.xcconfig"; sourceTree = "<group>"; };
6970
9D1DC7AE05F709A3F0E450DA /* Pods_AnimalsApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AnimalsApp.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7071
A1E75A013A1B19FF9D2B114B /* Pods_AnimalsApp_AnimalsAppUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AnimalsApp_AnimalsAppUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
72+
A458A085285E58CC0057BC34 /* FavoritesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesViewModel.swift; sourceTree = "<group>"; };
7173
A463D0132858EBBB00929A3C /* AnimalsApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnimalsApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
7274
A463D0162858EBBB00929A3C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7375
A463D0202858EBBB00929A3C /* AnimalsApp.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = AnimalsApp.xcdatamodel; sourceTree = "<group>"; };
@@ -96,8 +98,8 @@
9698
A463D070285A373700929A3C /* Animals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Animals.swift; sourceTree = "<group>"; };
9799
A463D073285A398900929A3C /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewModel.swift; sourceTree = "<group>"; };
98100
A463D077285A5A8000929A3C /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "OpenSans-Regular.ttf"; sourceTree = "<group>"; };
99-
A463D07B285B9B6300929A3C /* CoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreData.swift; sourceTree = "<group>"; };
100101
A463D079285B8D8D00929A3C /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
102+
A463D07B285B9B6300929A3C /* CoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreData.swift; sourceTree = "<group>"; };
101103
A463D07D285CF28200929A3C /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
102104
/* End PBXFileReference section */
103105

@@ -289,6 +291,7 @@
289291
children = (
290292
A463D073285A398900929A3C /* HomeViewModel.swift */,
291293
5CA996F7285A98FB00FF5D79 /* RegisterViewModel.swift */,
294+
A458A085285E58CC0057BC34 /* FavoritesViewModel.swift */,
292295
);
293296
path = "View Models";
294297
sourceTree = "<group>";
@@ -572,6 +575,7 @@
572575
A463D0572858F62600929A3C /* RegisterViewController.swift in Sources */,
573576
A463D0172858EBBB00929A3C /* AppDelegate.swift in Sources */,
574577
A463D071285A373800929A3C /* Animals.swift in Sources */,
578+
A458A086285E58CC0057BC34 /* FavoritesViewModel.swift in Sources */,
575579
A463D04B2858F39000929A3C /* MainTabBarController.swift in Sources */,
576580
A463D074285A398900929A3C /* HomeViewModel.swift in Sources */,
577581
A463D07A285B8D8E00929A3C /* Colors.swift in Sources */,

AnimalsApp/AnimalsApp/Services/CoreData.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ protocol CoreDataContract: AnyObject {
1818

1919
class CoreData: CoreDataContract {
2020
var managedContext: NSManagedObjectContext?
21-
var favoriteAnimals = [FavoriteAnimal]()
21+
static var favoriteAnimals = [FavoriteAnimal]() {
22+
didSet {
23+
notifyChanges?()
24+
}
25+
}
26+
27+
static var notifyChanges: (() -> Void)?
2228

2329
init() {
2430
managedContext = (UIApplication.shared.delegate as? AppDelegate)?
@@ -28,11 +34,11 @@ class CoreData: CoreDataContract {
2834

2935
func loadFavoriteAnimals(completion: @escaping () -> ()) {
3036
guard let managedContext = managedContext else { return }
31-
37+
3238
let fetchRequest: NSFetchRequest<FavoriteAnimal> = FavoriteAnimal.fetchRequest()
3339

3440
do {
35-
favoriteAnimals = try managedContext.fetch(fetchRequest)
41+
CoreData.favoriteAnimals = try managedContext.fetch(fetchRequest)
3642
completion()
3743
} catch let error as NSError {
3844
print("Could not fetch. \(error), \(error.userInfo)")
@@ -41,7 +47,7 @@ class CoreData: CoreDataContract {
4147

4248
func isFavorite(id: String) -> Bool {
4349

44-
for animal in favoriteAnimals {
50+
for animal in CoreData.favoriteAnimals {
4551
if animal.id == id {
4652
return true
4753
}
@@ -60,7 +66,7 @@ class CoreData: CoreDataContract {
6066
newFavoriteAnimal.descript = animal.description
6167
newFavoriteAnimal.age = Int32(animal.age ?? 0)
6268
newFavoriteAnimal.species = animal.species
63-
self.favoriteAnimals.append(newFavoriteAnimal)
69+
CoreData.favoriteAnimals.append(newFavoriteAnimal)
6470
}
6571

6672
func removeFavorite(id: String) {
@@ -69,10 +75,10 @@ class CoreData: CoreDataContract {
6975

7076
var count = 0
7177

72-
for animal in favoriteAnimals {
78+
for animal in CoreData.favoriteAnimals {
7379
if animal.id == id {
7480
let removeAnimal = animal
75-
favoriteAnimals.remove(at: count)
81+
CoreData.favoriteAnimals.remove(at: count)
7682
managedContext.delete(removeAnimal)
7783
}
7884
count += 1
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// FavoritesViewModel.swift
3+
// AnimalsApp
4+
//
5+
// Created by Laura Pinheiro Marson on 18/06/22.
6+
//
7+
8+
import Foundation
9+
10+
class FavoritesViewModel {
11+
var favoriteAnimals = [Animal]()
12+
13+
func getFavoriteAnimals(completion: @escaping () -> Void) {
14+
let coreDataAnimals = CoreData.favoriteAnimals
15+
favoriteAnimals.removeAll(keepingCapacity: true)
16+
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)
20+
}
21+
22+
completion()
23+
}
24+
25+
func numberOfRows() -> Int {
26+
return favoriteAnimals.count
27+
}
28+
29+
func modelAt(_ index: Int) -> Animal {
30+
return favoriteAnimals[index]
31+
}
32+
}

AnimalsApp/AnimalsApp/Views/Components/AnimalTableViewCell.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,14 @@ class AnimalTableViewCell: UITableViewCell {
4444
self.animalImage.layer.borderWidth = 0.5
4545
self.animalImage.layer.borderColor = UIColor.lightGray?.cgColor
4646

47-
let imageURL = animal.imageURL
48-
let placeholderImage = UIImage.imagePlaceHolder
47+
if let imageData = animal.imageData {
48+
animalImage.image = UIImage(data: imageData)
49+
} else {
50+
let imageURL = animal.imageURL
51+
let placeholderImage = UIImage.imagePlaceHolder
4952

50-
animalImage.sd_setImage(with: imageURL, placeholderImage: placeholderImage)
53+
animalImage.sd_setImage(with: imageURL, placeholderImage: placeholderImage)
54+
}
5155

5256
animal.isFavorite ?? false ? favoriteButton.setImage(.favorite, for: .normal) : favoriteButton.setImage(.notFavorite, for: .normal)
5357
}

AnimalsApp/AnimalsApp/Views/FavoritesViewController/FavoritesViewController.swift

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,27 @@
88
import UIKit
99

1010
class FavoritesViewController: UIViewController {
11-
11+
12+
var favoritesVM = FavoritesViewModel()
13+
14+
@IBOutlet weak var tableView: UITableView!
15+
1216
override func viewDidLoad() {
1317
super.viewDidLoad()
18+
19+
tableView.dataSource = self
20+
tableView.delegate = self
21+
22+
tableView.register(UINib(nibName: "AnimalTableViewCell", bundle: nil), forCellReuseIdentifier: "Animal")
1423

1524
setNavigationItems()
1625
}
26+
27+
override func viewWillAppear(_ animated: Bool) {
28+
super.viewWillAppear(animated)
29+
favoritesVM.getFavoriteAnimals() { [weak self] in self?.tableView.reloadData()
30+
}
31+
}
1732

1833
private func setNavigationItems() {
1934
title = "Favoritos"
@@ -28,3 +43,48 @@ class FavoritesViewController: UIViewController {
2843
}
2944

3045
}
46+
47+
// MARK: TableView Data Source
48+
extension FavoritesViewController: UITableViewDataSource {
49+
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
50+
return favoritesVM.numberOfRows()
51+
}
52+
53+
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
54+
55+
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Animal", for: indexPath) as? AnimalTableViewCell else {
56+
return UITableViewCell()
57+
}
58+
59+
cell.animal = favoritesVM.modelAt(indexPath.row)
60+
cell.index = indexPath.row
61+
cell.delegate = self
62+
cell.configure()
63+
64+
return cell
65+
}
66+
67+
}
68+
69+
// MARK: TableView Delegate
70+
extension FavoritesViewController: UITableViewDelegate {
71+
72+
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
73+
let detailVC = DetailViewController(nibName: "DetailViewController", bundle: nil)
74+
75+
//continuar
76+
77+
navigationController?.pushViewController(detailVC, animated: true)
78+
79+
tableView.deselectRow(at: indexPath, animated: true)
80+
}
81+
82+
}
83+
84+
// MARK: Action Delegate Protocol
85+
extension FavoritesViewController: ActionDelegateProtocol {
86+
func favoriteButtonTapped(at index: Int, with image: Data) {
87+
// homeVM.addOrRemoveFavorite(at: index, with: image)
88+
}
89+
}
90+
Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,50 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
3+
<device id="retina6_1" orientation="portrait" appearance="light"/>
34
<dependencies>
4-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
5+
<deployment identifier="iOS"/>
6+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
7+
<capability name="Named colors" minToolsVersion="9.0"/>
58
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
9+
<capability name="System colors in document resources" minToolsVersion="11.0"/>
610
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
711
</dependencies>
812
<objects>
9-
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="FavoritesViewController" customModuleProvider="target">
13+
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="FavoritesViewController" customModule="AnimalsApp" customModuleProvider="target">
1014
<connections>
15+
<outlet property="tableView" destination="Z7H-5c-G5G" id="KBe-qr-ZCy"/>
1116
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
1217
</connections>
1318
</placeholder>
1419
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
1520
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
16-
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
21+
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
1722
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18-
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
23+
<subviews>
24+
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="Z7H-5c-G5G">
25+
<rect key="frame" x="0.0" y="44" width="414" height="818"/>
26+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
27+
<color key="separatorColor" name="grayCellFrame"/>
28+
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
29+
</tableView>
30+
</subviews>
1931
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
32+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
33+
<constraints>
34+
<constraint firstItem="Z7H-5c-G5G" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" id="Gij-fh-f3w"/>
35+
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="Z7H-5c-G5G" secondAttribute="trailing" id="Mbr-5U-mqf"/>
36+
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="Z7H-5c-G5G" secondAttribute="bottom" id="OEE-7F-ts3"/>
37+
<constraint firstItem="Z7H-5c-G5G" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="e7r-Gn-PgY"/>
38+
</constraints>
39+
<point key="canvasLocation" x="132" y="33"/>
2040
</view>
2141
</objects>
42+
<resources>
43+
<namedColor name="grayCellFrame">
44+
<color red="0.63921568627450975" green="0.63921568627450975" blue="0.63921568627450975" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
45+
</namedColor>
46+
<systemColor name="systemBackgroundColor">
47+
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
48+
</systemColor>
49+
</resources>
2250
</document>

0 commit comments

Comments
 (0)