Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Viewmodel to BookmarkViewController. #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions DailyFeed.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
208FBB5B1EDB1C36009C2539 /* DailySourceItemiPadLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 208FBB5A1EDB1C36009C2539 /* DailySourceItemiPadLayout.swift */; };
20EA15751EA28C6700047523 /* Reach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20EA15741EA28C6700047523 /* Reach.swift */; };
953C685821A071CC006750F8 /* IconTransitions.json in Resources */ = {isa = PBXBuildFile; fileRef = 953C685721A071CC006750F8 /* IconTransitions.json */; };
99DAB4CC252EC0E5004EE15E /* BookmarkViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99DAB4CB252EC0E5004EE15E /* BookmarkViewModel.swift */; };
BF3E3EF3B745B55ADCBE90FA /* Pods_DailyFeed.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0F173573F8F2C56C6A3483F /* Pods_DailyFeed.framework */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -114,6 +115,7 @@
5FC3839392D2356ACF37A1F7 /* Pods_News_Now.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_News_Now.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7314A561F80C2D11A6AB0E63 /* Pods-DailyFeedTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DailyFeedTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DailyFeedTests/Pods-DailyFeedTests.release.xcconfig"; sourceTree = "<group>"; };
953C685721A071CC006750F8 /* IconTransitions.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = IconTransitions.json; sourceTree = "<group>"; };
99DAB4CB252EC0E5004EE15E /* BookmarkViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkViewModel.swift; sourceTree = "<group>"; };
D0F173573F8F2C56C6A3483F /* Pods_DailyFeed.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DailyFeed.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D1D7734AD5DFC5D8F8DD5CB0 /* Pods-News Now.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-News Now.release.xcconfig"; path = "Pods/Target Support Files/Pods-News Now/Pods-News Now.release.xcconfig"; sourceTree = "<group>"; };
E18B06086150616A4B3A60A3 /* Pods-News Now.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-News Now.debug.xcconfig"; path = "Pods/Target Support Files/Pods-News Now/Pods-News Now.debug.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -166,6 +168,7 @@
isa = PBXGroup;
children = (
1DAAF127242E55C300DF364F /* DailyFeed.entitlements */,
99DAB4CA252EC0CB004EE15E /* ViewModels */,
953C685121A070A5006750F8 /* 📦Model */,
953C685221A070CD006750F8 /* Views */,
953C685321A070EB006750F8 /* 📱Controllers */,
Expand Down Expand Up @@ -279,6 +282,14 @@
path = "Lottie Assets";
sourceTree = "<group>";
};
99DAB4CA252EC0CB004EE15E /* ViewModels */ = {
isa = PBXGroup;
children = (
99DAB4CB252EC0E5004EE15E /* BookmarkViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -465,6 +476,7 @@
063504FC1E151C4A002510B0 /* DFSafariViewController.swift in Sources */,
06D04C571E13948C0013B4AA /* TSImageView.swift in Sources */,
0635050E1E1BA50E002510B0 /* TSSpinnerView.swift in Sources */,
99DAB4CC252EC0E5004EE15E /* BookmarkViewModel.swift in Sources */,
063505021E15342C002510B0 /* NewsSourceViewController.swift in Sources */,
06D04C541E13945D0013B4AA /* DailyFeedItemCell.swift in Sources */,
06D04C4D1E1249430013B4AA /* DailyFeedModel.swift in Sources */,
Expand Down
80 changes: 80 additions & 0 deletions DailyFeed/ViewModels/BookmarkViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//
// BookmarkViewModel.swift
// DailyFeed
//
// Created by Kevin Vishal on 08/10/20.
// Copyright © 2020 trianz. All rights reserved.
//

import UIKit
import RealmSwift

class BookmarkViewModel: NSObject {

/// All news items
private(set) var newsItems: Results<DailyFeedRealmModel>!
/// Realm NotificationToken
private(set) var notificationToken: NotificationToken? = nil

typealias ObserverHandler = ((RealmCollectionChange<Results<DailyFeedRealmModel>>)) -> Void

/// Number of news items.
var numberOfNewsItems : Int {
return newsItems.count
}
/// Number of sections in the view.
func numberOfSections() -> Int {
return 1
}
/// Number of rows in each section.
func numberOfRowsInSection(section : Int) -> Int {
return newsItems.count
}
/// DailyFeed for each row in section.
func getDailyFeedForIndex(_ index : Int) -> DailyFeedRealmModel {
return newsItems[index]
}

func observeDatabase(_ handler : @escaping ObserverHandler) {

let realm = try! Realm()
newsItems = realm.objects(DailyFeedRealmModel.self)
notificationToken = newsItems.observe({ (changes) in
handler(changes)
})
}

///Delete Feed Item
func removeDailyFeed(_ feedItem : DailyFeedRealmModel) -> Void {
let realm = try! Realm()
try! realm.write {
realm.delete(feedItem)
}
}

///Add Feed Item
func addDailyFeed(_ dailyFeedModel : DailyFeedModel?) -> Void {
let realm = try! Realm()
guard let dailyfeedmodel = dailyFeedModel else {
return
}
let dailyfeedRealmModel = DailyFeedRealmModel.toDailyFeedRealmModel(from: dailyfeedmodel)
try! realm.write {
realm.add(dailyfeedRealmModel, update: .all)
}
}

///Empty Dataset Title
var noDataErrorTitle : NSAttributedString {
let str = "No Articles Bookmarked"
let attrs = [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)]
return NSAttributedString(string: str, attributes: attrs)
}

///Empty Dataset Description
var noDataErrorDescription : NSAttributedString {
let str = "Your Bookmarks will appear here."
let attrs = [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)]
return NSAttributedString(string: str, attributes: attrs)
}
}
92 changes: 32 additions & 60 deletions DailyFeed/📱Controllers/BookmarkViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@
//

import UIKit
import RealmSwift
import CoreSpotlight
import MobileCoreServices
import DZNEmptyDataSet
import RealmSwift

class BookmarkViewController: UIViewController {

@IBOutlet weak var bookmarkCollectionView: UICollectionView!

var newsItems: Results<DailyFeedRealmModel>!

var notificationToken: NotificationToken? = nil
@IBOutlet private weak var bookmarkCollectionView: UICollectionView!
private var bookmarkViewModel = BookmarkViewModel()

override func viewDidLoad() {
super.viewDidLoad()
Expand All @@ -27,34 +24,29 @@ class BookmarkViewController: UIViewController {
if #available(iOS 11.0, *) {
bookmarkCollectionView?.dropDelegate = self
}
observeDatabase()
///Register viewmodel observer here
bookmarkViewModel.observeDatabase { (changes) in
self.observeForFeeds(changes: changes)
}
}

func observeDatabase() {

let realm = try! Realm()
newsItems = realm.objects(DailyFeedRealmModel.self)

notificationToken = newsItems.observe { [weak self] (changes: RealmCollectionChange) in
guard let collectionview = self?.bookmarkCollectionView else { return }
switch changes {
case .initial:
collectionview.reloadData()
break
case .update( _, let deletions, let insertions, _):
collectionview.performBatchUpdates({
collectionview.deleteItems(at: deletions.map({ IndexPath(row: $0, section: 0) }))

collectionview.insertItems(at: insertions.map({ IndexPath(row: $0, section: 0) }))

}, completion: nil)

if self?.newsItems.count == 0 || self?.newsItems.count == 1 { collectionview.reloadEmptyDataSet() }
break
case .error(let error):
fatalError("\(error)")
break
}
private func observeForFeeds(changes: RealmCollectionChange<Results<DailyFeedRealmModel>>) {
guard let collectionview = self.bookmarkCollectionView else { return }
switch changes {
case .initial:
collectionview.reloadData()
break
case .update( _, let deletions, let insertions, _):
collectionview.performBatchUpdates({
collectionview.deleteItems(at: deletions.map({ IndexPath(row: $0, section: 0) }))
collectionview.insertItems(at: insertions.map({ IndexPath(row: $0, section: 0) }))
}, completion: nil)

if self.bookmarkViewModel.numberOfNewsItems == 0 || self.bookmarkViewModel.numberOfNewsItems == 1 { collectionview.reloadEmptyDataSet() }
break
case .error(let error):
fatalError("\(error)")
break
}
}

Expand All @@ -64,15 +56,11 @@ class BookmarkViewController: UIViewController {
guard let cell = sender as? UICollectionViewCell else { return }
guard let indexpath = self.bookmarkCollectionView.indexPath(for: cell) else { return }
vc.receivedItemNumber = indexpath.row + 1
vc.receivedNewsItem = newsItems[indexpath.row]
vc.receivedNewsItem = bookmarkViewModel.getDailyFeedForIndex(indexpath.row)
}
}
}

deinit {
notificationToken?.invalidate()
}

override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Expand All @@ -83,20 +71,16 @@ class BookmarkViewController: UIViewController {
extension BookmarkViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return newsItems.count
return bookmarkViewModel.numberOfRowsInSection(section: section)
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let newsCell = collectionView.dequeueReusableCell(withReuseIdentifier: R.reuseIdentifier.bookmarkItemsCell, for: indexPath)
newsCell?.configure(with: newsItems[indexPath.row])
newsCell?.configure(with: bookmarkViewModel.getDailyFeedForIndex(indexPath.row))
newsCell?.cellTapped = { cell in
if let cellToDelete = self.bookmarkCollectionView.indexPath(for: cell)?.row {
let item = self.newsItems[cellToDelete]
let realm = try! Realm()
try! realm.write {
realm.delete(item)
}

let item = self.bookmarkViewModel.getDailyFeedForIndex(cellToDelete) //self.newsItems[cellToDelete]
self.bookmarkViewModel.removeDailyFeed(item)
}
}
return newsCell!
Expand All @@ -116,15 +100,11 @@ extension BookmarkViewController: UICollectionViewDelegate, UICollectionViewData
extension BookmarkViewController: DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {

func title(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString? {
let str = "No Articles Bookmarked"
let attrs = [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)]
return NSAttributedString(string: str, attributes: attrs)
return bookmarkViewModel.noDataErrorTitle
}

func description(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString? {
let str = "Your Bookmarks will appear here."
let attrs = [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)]
return NSAttributedString(string: str, attributes: attrs)
return bookmarkViewModel.noDataErrorDescription
}

func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
Expand All @@ -151,15 +131,7 @@ extension BookmarkViewController: UICollectionViewDropDelegate {
if itemProvider.canLoadObject(ofClass: DailyFeedModel.self) {
itemProvider.loadObject(ofClass: DailyFeedModel.self) { (object, error) in
DispatchQueue.main.async {
let realm = try! Realm()
if let dailyfeedmodel = object as? DailyFeedModel {
let dailyfeedRealmModel = DailyFeedRealmModel.toDailyFeedRealmModel(from: dailyfeedmodel)
try! realm.write {
realm.add(dailyfeedRealmModel, update: .all)
}
} else {
//self.displayError(error)
}
self.bookmarkViewModel.addDailyFeed(object as? DailyFeedModel)
}
}
}
Expand Down