Skip to content

Commit 0ba00a9

Browse files
committed
Added custom CoreData repositories and unit tests
1 parent 33fe8b8 commit 0ba00a9

File tree

14 files changed

+383
-44
lines changed

14 files changed

+383
-44
lines changed

NYTimes.xcodeproj/project.pbxproj

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
/* Begin PBXBuildFile section */
1010
7524922624D053CE00B1ACA5 /* NewsFeedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7524922524D053CE00B1ACA5 /* NewsFeedView.swift */; };
11+
754C9A1B24D0C40700706469 /* PlaceholderBookmarkRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C9A1A24D0C40700706469 /* PlaceholderBookmarkRepository.swift */; };
12+
754C9A1D24D1500C00706469 /* Article.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C9A1C24D1500C00706469 /* Article.swift */; };
13+
754C9A2024D158B000706469 /* CDBookmarks+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C9A1E24D158B000706469 /* CDBookmarks+CoreDataClass.swift */; };
14+
754C9A2124D158B000706469 /* CDBookmarks+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754C9A1F24D158B000706469 /* CDBookmarks+CoreDataProperties.swift */; };
1115
754FAFE724D0308900ACFE9E /* Category.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754FAFE624D0308900ACFE9E /* Category.swift */; };
1216
7557FA7B24D0271400F80607 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7557FA7A24D0271400F80607 /* AppDelegate.swift */; };
1317
7557FA7D24D0271400F80607 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7557FA7C24D0271400F80607 /* SceneDelegate.swift */; };
@@ -23,11 +27,10 @@
2327
75C2758324D0AC2C00A7A651 /* NewsFeedViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C2758224D0AC2C00A7A651 /* NewsFeedViewModel.swift */; };
2428
75C2758524D0ACD100A7A651 /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C2758424D0ACD100A7A651 /* Repository.swift */; };
2529
75C2758824D0AEBC00A7A651 /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = 75C2758724D0AEBC00A7A651 /* SwiftSoup */; };
26-
75C2759624D0B42700A7A651 /* CDBookmarks+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C2759424D0B42700A7A651 /* CDBookmarks+CoreDataClass.swift */; };
27-
75C2759724D0B42700A7A651 /* CDBookmarks+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C2759524D0B42700A7A651 /* CDBookmarks+CoreDataProperties.swift */; };
2830
75C2759924D0BA1B00A7A651 /* BookmarksRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C2759824D0BA1B00A7A651 /* BookmarksRepository.swift */; };
2931
75C2759B24D0BA6B00A7A651 /* Bookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C2759A24D0BA6B00A7A651 /* Bookmark.swift */; };
3032
75C2759D24D0BB6C00A7A651 /* PersistenceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C2759C24D0BB6C00A7A651 /* PersistenceManager.swift */; };
33+
75E694AC24D1606400D4C04C /* BookmarksViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E694AB24D1606400D4C04C /* BookmarksViewModelTest.swift */; };
3134
/* End PBXBuildFile section */
3235

3336
/* Begin PBXContainerItemProxy section */
@@ -42,6 +45,10 @@
4245

4346
/* Begin PBXFileReference section */
4447
7524922524D053CE00B1ACA5 /* NewsFeedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsFeedView.swift; sourceTree = "<group>"; };
48+
754C9A1A24D0C40700706469 /* PlaceholderBookmarkRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderBookmarkRepository.swift; sourceTree = "<group>"; };
49+
754C9A1C24D1500C00706469 /* Article.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Article.swift; sourceTree = "<group>"; };
50+
754C9A1E24D158B000706469 /* CDBookmarks+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CDBookmarks+CoreDataClass.swift"; sourceTree = "<group>"; };
51+
754C9A1F24D158B000706469 /* CDBookmarks+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CDBookmarks+CoreDataProperties.swift"; sourceTree = "<group>"; };
4552
754FAFE624D0308900ACFE9E /* Category.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Category.swift; sourceTree = "<group>"; };
4653
7557FA7724D0271400F80607 /* NYTimes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NYTimes.app; sourceTree = BUILT_PRODUCTS_DIR; };
4754
7557FA7A24D0271400F80607 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -60,11 +67,10 @@
6067
75C2758024D0AC1600A7A651 /* BookmarksViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksViewModel.swift; sourceTree = "<group>"; };
6168
75C2758224D0AC2C00A7A651 /* NewsFeedViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsFeedViewModel.swift; sourceTree = "<group>"; };
6269
75C2758424D0ACD100A7A651 /* Repository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Repository.swift; sourceTree = "<group>"; };
63-
75C2759424D0B42700A7A651 /* CDBookmarks+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CDBookmarks+CoreDataClass.swift"; sourceTree = "<group>"; };
64-
75C2759524D0B42700A7A651 /* CDBookmarks+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CDBookmarks+CoreDataProperties.swift"; sourceTree = "<group>"; };
6570
75C2759824D0BA1B00A7A651 /* BookmarksRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksRepository.swift; sourceTree = "<group>"; };
6671
75C2759A24D0BA6B00A7A651 /* Bookmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bookmark.swift; sourceTree = "<group>"; };
6772
75C2759C24D0BB6C00A7A651 /* PersistenceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceManager.swift; sourceTree = "<group>"; };
73+
75E694AB24D1606400D4C04C /* BookmarksViewModelTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksViewModelTest.swift; sourceTree = "<group>"; };
6874
/* End PBXFileReference section */
6975

7076
/* Begin PBXFrameworksBuildPhase section */
@@ -86,6 +92,14 @@
8692
/* End PBXFrameworksBuildPhase section */
8793

8894
/* Begin PBXGroup section */
95+
754C9A1924D0C3E900706469 /* Placeholder Repositories */ = {
96+
isa = PBXGroup;
97+
children = (
98+
754C9A1A24D0C40700706469 /* PlaceholderBookmarkRepository.swift */,
99+
);
100+
path = "Placeholder Repositories";
101+
sourceTree = "<group>";
102+
};
89103
7557FA6E24D0271400F80607 = {
90104
isa = PBXGroup;
91105
children = (
@@ -133,6 +147,7 @@
133147
children = (
134148
7557FA9424D0271500F80607 /* NYTimesTests.swift */,
135149
7557FA9624D0271500F80607 /* Info.plist */,
150+
75E694AB24D1606400D4C04C /* BookmarksViewModelTest.swift */,
136151
);
137152
path = NYTimesTests;
138153
sourceTree = "<group>";
@@ -143,6 +158,7 @@
143158
75C2759324D0B3D900A7A651 /* Coredata model */,
144159
754FAFE624D0308900ACFE9E /* Category.swift */,
145160
75C2759A24D0BA6B00A7A651 /* Bookmark.swift */,
161+
754C9A1C24D1500C00706469 /* Article.swift */,
146162
);
147163
path = Model;
148164
sourceTree = "<group>";
@@ -189,15 +205,16 @@
189205
75C2759324D0B3D900A7A651 /* Coredata model */ = {
190206
isa = PBXGroup;
191207
children = (
192-
75C2759424D0B42700A7A651 /* CDBookmarks+CoreDataClass.swift */,
193-
75C2759524D0B42700A7A651 /* CDBookmarks+CoreDataProperties.swift */,
208+
754C9A1E24D158B000706469 /* CDBookmarks+CoreDataClass.swift */,
209+
754C9A1F24D158B000706469 /* CDBookmarks+CoreDataProperties.swift */,
194210
);
195211
path = "Coredata model";
196212
sourceTree = "<group>";
197213
};
198214
75C2759E24D0BBCC00A7A651 /* Repository */ = {
199215
isa = PBXGroup;
200216
children = (
217+
754C9A1924D0C3E900706469 /* Placeholder Repositories */,
201218
75C2758424D0ACD100A7A651 /* Repository.swift */,
202219
75C2759824D0BA1B00A7A651 /* BookmarksRepository.swift */,
203220
);
@@ -313,19 +330,21 @@
313330
files = (
314331
7557FA8024D0271400F80607 /* NYTimes.xcdatamodeld in Sources */,
315332
75C2759924D0BA1B00A7A651 /* BookmarksRepository.swift in Sources */,
333+
754C9A2024D158B000706469 /* CDBookmarks+CoreDataClass.swift in Sources */,
334+
754C9A1D24D1500C00706469 /* Article.swift in Sources */,
316335
7557FA7B24D0271400F80607 /* AppDelegate.swift in Sources */,
317336
75C2758124D0AC1600A7A651 /* BookmarksViewModel.swift in Sources */,
318337
75C2758324D0AC2C00A7A651 /* NewsFeedViewModel.swift in Sources */,
319338
75C2759B24D0BA6B00A7A651 /* Bookmark.swift in Sources */,
320339
75C2757F24D0A5E500A7A651 /* BookmarksView.swift in Sources */,
321340
7557FA8224D0271400F80607 /* RootView.swift in Sources */,
322-
75C2759624D0B42700A7A651 /* CDBookmarks+CoreDataClass.swift in Sources */,
341+
754C9A2124D158B000706469 /* CDBookmarks+CoreDataProperties.swift in Sources */,
323342
75C2758524D0ACD100A7A651 /* Repository.swift in Sources */,
324343
7557FAA024D0277200F80607 /* CategorySelector.swift in Sources */,
325344
7524922624D053CE00B1ACA5 /* NewsFeedView.swift in Sources */,
326345
7557FA7D24D0271400F80607 /* SceneDelegate.swift in Sources */,
327346
754FAFE724D0308900ACFE9E /* Category.swift in Sources */,
328-
75C2759724D0B42700A7A651 /* CDBookmarks+CoreDataProperties.swift in Sources */,
347+
754C9A1B24D0C40700706469 /* PlaceholderBookmarkRepository.swift in Sources */,
329348
75C2759D24D0BB6C00A7A651 /* PersistenceManager.swift in Sources */,
330349
);
331350
runOnlyForDeploymentPostprocessing = 0;
@@ -334,6 +353,7 @@
334353
isa = PBXSourcesBuildPhase;
335354
buildActionMask = 2147483647;
336355
files = (
356+
75E694AC24D1606400D4C04C /* BookmarksViewModelTest.swift in Sources */,
337357
7557FA9524D0271500F80607 /* NYTimesTests.swift in Sources */,
338358
);
339359
runOnlyForDeploymentPostprocessing = 0;

NYTimes/Model/Article.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// Article.swift
3+
// NYTimes
4+
//
5+
// Created by Waseem Akram on 29/07/20.
6+
// Copyright © 2020 Waseem Akram. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
public class Article:NSObject,Codable {
12+
13+
var id: UUID
14+
var url: String
15+
var title: String
16+
var subtitle: String
17+
var author: String
18+
19+
20+
init(id: UUID = UUID(),url: String, title: String, subtitle: String, author: String) {
21+
self.id = id
22+
self.url = url
23+
self.title = title
24+
self.subtitle = subtitle
25+
self.author = author
26+
}
27+
28+
}
29+

NYTimes/Model/Bookmark.swift

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,20 @@
88

99
import Foundation
1010

11-
struct Bookmark {
11+
struct Bookmark {
1212
var id: UUID
13-
var url: String
14-
var title: String
15-
var subtitle: String
16-
var author: String
13+
var article:Article
1714
var index: Int16
15+
16+
init(from cdBookmark:CDBookmarks) {
17+
self.id = cdBookmark.id!
18+
self.article = cdBookmark.article!
19+
self.index = cdBookmark.index
20+
}
21+
22+
init(id: UUID = UUID(), article: Article, index: Int16) {
23+
self.id = id
24+
self.article = article
25+
self.index = index
26+
}
1827
}

NYTimes/Model/Coredata model/CDBookmarks+CoreDataProperties.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ extension CDBookmarks {
1818
}
1919

2020
@NSManaged public var id: UUID?
21-
@NSManaged public var url: String?
22-
@NSManaged public var title: String?
23-
@NSManaged public var subtitle: String?
24-
@NSManaged public var author: String?
2521
@NSManaged public var index: Int16
22+
@NSManaged public var article: Article?
2623

2724
}
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
22
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="16119" systemVersion="19G46c" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
33
<entity name="CDBookmarks" representedClassName="CDBookmarks" syncable="YES">
4-
<attribute name="author" attributeType="String"/>
4+
<attribute name="article" attributeType="Transformable" customClassName="Article"/>
55
<attribute name="id" attributeType="UUID" usesScalarValueType="NO"/>
66
<attribute name="index" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
7-
<attribute name="subtitle" attributeType="String"/>
8-
<attribute name="title" attributeType="String"/>
9-
<attribute name="url" attributeType="String"/>
107
<uniquenessConstraints>
118
<uniquenessConstraint>
129
<constraint value="id"/>
1310
</uniquenessConstraint>
1411
</uniquenessConstraints>
1512
</entity>
1613
<elements>
17-
<element name="CDBookmarks" positionX="-63" positionY="-18" width="128" height="133"/>
14+
<element name="CDBookmarks" positionX="-63" positionY="-18" width="128" height="88"/>
1815
</elements>
1916
</model>

NYTimes/Persistence/PersistenceManager.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@
88

99
import CoreData
1010

11+
/// PersistenceManager is a Singleton which manages the
12+
/// coredata core operations like creating containers, context and handles saving of the data
1113
final class PersistenceManager {
1214

15+
private init(){}
16+
17+
static let shared = PersistenceManager()
18+
1319
lazy var persistentContainer: NSPersistentContainer = {
1420
let container = NSPersistentContainer(name: "NYTimes")
1521
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
@@ -19,6 +25,8 @@ final class PersistenceManager {
1925
})
2026
return container
2127
}()
28+
29+
lazy var context = persistentContainer.viewContext
2230

2331
func saveContext () -> Bool {
2432
let context = persistentContainer.viewContext
@@ -35,4 +43,17 @@ final class PersistenceManager {
3543
return false
3644
}
3745

46+
func fetch<T:NSManagedObject>(managedObject: T.Type) -> [T]? {
47+
do {
48+
guard let result = try PersistenceManager.shared.context.fetch(managedObject.fetchRequest()) as? [T] else {
49+
return nil
50+
}
51+
52+
return result
53+
}catch let error {
54+
debugPrint(error)
55+
return nil
56+
}
57+
}
58+
3859
}

NYTimes/Repository/BookmarksRepository.swift

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,63 @@
77
//
88

99
import Foundation
10+
import CoreData
1011

12+
protocol BookmarksRepository {
13+
14+
func upsert(article:Article) -> Bool
15+
func get(index:Int16) -> Bookmark?
16+
func getAll() -> [Bookmark]
17+
func delete(index:Int16) -> Bool
18+
func deleteAll() -> Bool
19+
func swapIndex(source:Int16,destination:Int16)
20+
func getBookmarksCount() -> Int
21+
func updateOtherBookmarksIndex(after:Int16)
1122

12-
class BookmarksRepository:Repository {
13-
14-
typealias T = Bookmark
23+
}
24+
25+
class BookmarksDataRepository:BookmarksRepository {
1526

16-
func upsert(data: Bookmark) -> Bool {
27+
func upsert(article: Article) -> Bool {
1728
return true
1829
}
1930

20-
func get(id: UUID) -> Bookmark {
21-
return Bookmark(id: UUID(), url: "", title: "", subtitle: "", author: "", index: 0)
31+
func get(index: Int16) -> Bookmark? {
32+
let fetchRequest = NSFetchRequest<CDBookmarks>(entityName: "CDBookmarks")
33+
fetchRequest.predicate = NSPredicate(format: "index == %@", index as CVarArg)
34+
do {
35+
let result = try PersistenceManager.shared.context.fetch(fetchRequest).first
36+
if let result = result {
37+
return Bookmark(from: result)
38+
}
39+
}catch let error {
40+
debugPrint(error.localizedDescription)
41+
}
42+
return nil
2243
}
2344

24-
func getAll() -> [Bookmark] {
45+
46+
func getAll() -> [Bookmark] {
2547
return [Bookmark]()
2648
}
2749

28-
func delete(id: UUID) -> Bool {
50+
func delete(index: Int16) -> Bool {
2951
return true
3052
}
3153

32-
func deleteAll() -> Bool {
54+
func deleteAll() -> Bool {
3355
return true
3456
}
3557

58+
func swapIndex(source: Int16, destination: Int16) {
59+
60+
}
61+
62+
func getBookmarksCount() -> Int {
63+
return 0
64+
}
65+
66+
func updateOtherBookmarksIndex(after:Int16){
67+
}
68+
3669
}

0 commit comments

Comments
 (0)