Skip to content
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
36 changes: 26 additions & 10 deletions Example/CoreDataManager.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
607FACEC1AFB9204008FA782 /* SetupTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* SetupTestCase.swift */; };
A41E80C01BA5AA1500FEA2B9 /* SerializerTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = A41E80BF1BA5AA1500FEA2B9 /* SerializerTestCase.swift */; };
A4758E7B1B9B226800D6CBCF /* CoreDataManager.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = A4758E791B9B226800D6CBCF /* CoreDataManager.xcdatamodeld */; };
A4758EC61B9BA21300D6CBCF /* Click.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4758EC51B9BA21300D6CBCF /* Click.swift */; };
A4758ECF1B9C622B00D6CBCF /* Batch.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4758ECE1B9C622B00D6CBCF /* Batch.swift */; };
A4758ED51B9C932500D6CBCF /* ContextTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4758ED01B9C919B00D6CBCF /* ContextTestCase.swift */; };
A4758ED61B9C932500D6CBCF /* ManagedObjectManagerTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4758ED21B9C925A00D6CBCF /* ManagedObjectManagerTestCase.swift */; };
EEF720F06FDCAA15029A3DE3 /* Pods_CoreDataManager_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD20E1BD1E6D716F413BF29F /* Pods_CoreDataManager_Tests.framework */; };
F85D4950276F836B007AFA5A /* Click+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85D4947276F8306007AFA5A /* Click+CoreDataProperties.swift */; };
F85D4951276F836B007AFA5A /* Batch+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85D4945276F8306007AFA5A /* Batch+CoreDataProperties.swift */; };
F85D4952276F836B007AFA5A /* Batch+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85D4944276F8306007AFA5A /* Batch+CoreDataClass.swift */; };
F85D4953276F836B007AFA5A /* Point+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85D4946276F8306007AFA5A /* Point+CoreDataClass.swift */; };
F85D4954276F836B007AFA5A /* Point+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85D4948276F8306007AFA5A /* Point+CoreDataProperties.swift */; };
F85D4955276F836B007AFA5A /* Click+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85D4949276F8306007AFA5A /* Click+CoreDataClass.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -50,15 +54,19 @@
607FACEB1AFB9204008FA782 /* SetupTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupTestCase.swift; sourceTree = "<group>"; };
A41E80BF1BA5AA1500FEA2B9 /* SerializerTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerializerTestCase.swift; sourceTree = "<group>"; };
A4758E7A1B9B226800D6CBCF /* CoreDataManager.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = CoreDataManager.xcdatamodel; sourceTree = "<group>"; };
A4758EC51B9BA21300D6CBCF /* Click.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Click.swift; sourceTree = "<group>"; };
A4758ECE1B9C622B00D6CBCF /* Batch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Batch.swift; path = Models/Batch.swift; sourceTree = "<group>"; };
A4758ED01B9C919B00D6CBCF /* ContextTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContextTestCase.swift; sourceTree = "<group>"; };
A4758ED21B9C925A00D6CBCF /* ManagedObjectManagerTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedObjectManagerTestCase.swift; sourceTree = "<group>"; };
C289BEA78384DD3893AB5CDE /* CoreDataManager.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CoreDataManager.podspec; path = ../CoreDataManager.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
CD20E1BD1E6D716F413BF29F /* Pods_CoreDataManager_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CoreDataManager_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D74A19219C9FE0096BC6F3D9 /* Pods_CoreDataManager_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CoreDataManager_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D86CA9C21793D2D2696FBE74 /* Pods-CoreDataManager_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreDataManager_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreDataManager_Example/Pods-CoreDataManager_Example.debug.xcconfig"; sourceTree = "<group>"; };
DBB95AD69E69A34BAADE25EB /* Pods-CoreDataManager_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreDataManager_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreDataManager_Tests/Pods-CoreDataManager_Tests.debug.xcconfig"; sourceTree = "<group>"; };
F85D4944276F8306007AFA5A /* Batch+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Batch+CoreDataClass.swift"; path = "Models/Batch+CoreDataClass.swift"; sourceTree = "<group>"; };
F85D4945276F8306007AFA5A /* Batch+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Batch+CoreDataProperties.swift"; path = "Models/Batch+CoreDataProperties.swift"; sourceTree = "<group>"; };
F85D4946276F8306007AFA5A /* Point+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Point+CoreDataClass.swift"; path = "Models/Point+CoreDataClass.swift"; sourceTree = "<group>"; };
F85D4947276F8306007AFA5A /* Click+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Click+CoreDataProperties.swift"; path = "Models/Click+CoreDataProperties.swift"; sourceTree = "<group>"; };
F85D4948276F8306007AFA5A /* Point+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Point+CoreDataProperties.swift"; path = "Models/Point+CoreDataProperties.swift"; sourceTree = "<group>"; };
F85D4949276F8306007AFA5A /* Click+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Click+CoreDataClass.swift"; path = "Models/Click+CoreDataClass.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -159,8 +167,12 @@
A4758EC71B9BA21A00D6CBCF /* Models */ = {
isa = PBXGroup;
children = (
A4758ECE1B9C622B00D6CBCF /* Batch.swift */,
A4758EC51B9BA21300D6CBCF /* Click.swift */,
F85D4944276F8306007AFA5A /* Batch+CoreDataClass.swift */,
F85D4945276F8306007AFA5A /* Batch+CoreDataProperties.swift */,
F85D4949276F8306007AFA5A /* Click+CoreDataClass.swift */,
F85D4947276F8306007AFA5A /* Click+CoreDataProperties.swift */,
F85D4946276F8306007AFA5A /* Point+CoreDataClass.swift */,
F85D4948276F8306007AFA5A /* Point+CoreDataProperties.swift */,
);
name = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -352,10 +364,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A4758EC61B9BA21300D6CBCF /* Click.swift in Sources */,
607FACD81AFB9204008FA782 /* ClickViewController.swift in Sources */,
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
A4758ECF1B9C622B00D6CBCF /* Batch.swift in Sources */,
F85D4955276F836B007AFA5A /* Click+CoreDataClass.swift in Sources */,
F85D4953276F836B007AFA5A /* Point+CoreDataClass.swift in Sources */,
F85D4950276F836B007AFA5A /* Click+CoreDataProperties.swift in Sources */,
F85D4951276F836B007AFA5A /* Batch+CoreDataProperties.swift in Sources */,
F85D4952276F836B007AFA5A /* Batch+CoreDataClass.swift in Sources */,
F85D4954276F836B007AFA5A /* Point+CoreDataProperties.swift in Sources */,
A4758E7B1B9B226800D6CBCF /* CoreDataManager.xcdatamodeld in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -449,7 +465,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -498,7 +514,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
Expand Down
19 changes: 0 additions & 19 deletions Example/CoreDataManager/Click.swift

This file was deleted.

125 changes: 56 additions & 69 deletions Example/CoreDataManager/ClickViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,74 +10,84 @@ import CoreData
import CoreDataManager
import UIKit

class ClickViewController: UITableViewController, NSFetchedResultsControllerDelegate {

class ClickViewController: UITableViewController {
private let cdm = CoreDataManager.sharedInstance
private var thisBatchID: NSNumber!
private lazy var thisBatchID: Int = {
let lastBatchID = (cdm.mainContext.managerFor(Batch.self).max("id") as? Int) ?? 0
return lastBatchID + 1
}()

// MARK: - Fetched results controller

lazy var fetchedResultsController: NSFetchedResultsController<Click> = {
let fetchRequest = NSFetchRequest<Click>(entityName: "Click")
let sortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
let fetchedResultsController = NSFetchedResultsController<Click>(fetchRequest: fetchRequest, managedObjectContext: cdm.mainContext, sectionNameKeyPath: "batch.name", cacheName: nil)
fetchedResultsController.delegate = self
try? fetchedResultsController.performFetch()
return fetchedResultsController
}()

override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem
navigationItem.leftBarButtonItem = editButtonItem

let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(ClickViewController.insertNewClick(sender:)))
self.navigationItem.rightBarButtonItem = addButton

let lastBatchID = (self.cdm.mainContext.managerFor(Batch.self).max("id") as? NSNumber) ?? 0
self.thisBatchID = NSNumber(integerLiteral: lastBatchID.intValue + 1)
navigationItem.rightBarButtonItem = addButton
}

@objc func insertNewClick(sender: AnyObject) {

let context = self.cdm.backgroundContext
context.perform {
let clickManager = context.managerFor(Click.self)
let backgroundContext = cdm.backgroundContext
backgroundContext.perform {
let clickManager = backgroundContext.managerFor(Click.self)
let lastClickID = (clickManager.max("clickID") as? Int) ?? 0

let newClick = NSEntityDescription.insertNewObject(forEntityName: "Click", into: context) as! Click
newClick.timeStamp = Date()
newClick.clickID = NSNumber(integerLiteral: lastClickID + 1)
let newClick = Click.insert(into: backgroundContext)
newClick?.timeStamp = Date()
newClick?.clickID = NSNumber(value: lastClickID + 1)

if let batch = context.managerFor(Batch.self).filter(format: "id = %d", self.thisBatchID).first {
newClick.batch = batch
if let batch = backgroundContext.managerFor(Batch.self).filter(format: "id = %d", self.thisBatchID).first {
newClick?.batch = batch
} else {
let newBatch = NSEntityDescription.insertNewObject(forEntityName: "Batch", into: context) as! Batch

newBatch.id = self.thisBatchID
newBatch.name = "Batch \(self.thisBatchID.intValue)"
newClick.batch = newBatch
let newBatch = Batch.insert(into: backgroundContext)
newBatch?.id = NSNumber(value: self.thisBatchID)
newBatch?.name = "Batch \(self.thisBatchID)"
newClick?.batch = newBatch
}
try! context.saveIfChanged()
try? backgroundContext.saveIfChanged()
}
}

// MARK: - Private

private func configureCell(cell: UITableViewCell, atIndexPath indexPath: IndexPath) {
let object = self.fetchedResultsController.object(at: indexPath)
cell.textLabel!.text = object.timeStamp.description
let object = fetchedResultsController.object(at: indexPath)
cell.textLabel?.text = object.timeStamp?.description
}

// MARK: - Table View

override func numberOfSections(in tableView: UITableView) -> Int {
return self.fetchedResultsController.sections?.count ?? 0
return fetchedResultsController.sections?.count ?? 0
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let firstClick = self.fetchedResultsController.object(at: IndexPath(row: 0, section: section))
let firstClick = fetchedResultsController.object(at: IndexPath(row: 0, section: section))

return firstClick.batch.name
return firstClick.batch?.name
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController.sections![section]
let sectionInfo = fetchedResultsController.sections![section]
return sectionInfo.numberOfObjects
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ClickCell", for: indexPath)
self.configureCell(cell: cell, atIndexPath: indexPath)
configureCell(cell: cell, atIndexPath: indexPath)
return cell
}

Expand All @@ -88,50 +98,29 @@ class ClickViewController: UITableViewController, NSFetchedResultsControllerDele

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let click = self.fetchedResultsController.object(at: indexPath)
let click = fetchedResultsController.object(at: indexPath)
let clickID = click.clickID

let context = self.cdm.backgroundContext
let context = cdm.backgroundContext
context.perform {
_ = context.managerFor(Click.self).filter(format: "clickID = %@", clickID).delete()
try! context.saveIfChanged()
_ = context.managerFor(Click.self).filter(format: "clickID = %@", clickID as CVarArg).delete()
try? context.saveIfChanged()
}
}
}

// MARK: - Fetched results controller

var fetchedResultsController: NSFetchedResultsController<Click> {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}

let fetchRequest = NSFetchRequest<Click>(entityName: "Click")

let sortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)

fetchRequest.sortDescriptors = [sortDescriptor]

let aFetchedResultsController = NSFetchedResultsController<Click>(fetchRequest: fetchRequest, managedObjectContext: self.cdm.mainContext, sectionNameKeyPath: "batch.name", cacheName: nil)
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController

try! _fetchedResultsController!.performFetch()

return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController<Click>? = nil

}

extension ClickViewController: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.beginUpdates()
tableView.beginUpdates()
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
switch type {
case .insert:
self.tableView.insertSections(IndexSet([sectionIndex]), with: .fade)
tableView.insertSections(IndexSet([sectionIndex]), with: .fade)
case .delete:
self.tableView.deleteSections(IndexSet([sectionIndex]), with: .fade)
tableView.deleteSections(IndexSet([sectionIndex]), with: .fade)
default:
return
}
Expand All @@ -140,22 +129,20 @@ class ClickViewController: UITableViewController, NSFetchedResultsControllerDele
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
self.tableView.insertRows(at: [newIndexPath!], with: .fade)
tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
self.tableView.deleteRows(at: [indexPath!], with: .fade)
tableView.deleteRows(at: [indexPath!], with: .fade)
case .update:
self.configureCell(cell: self.tableView.cellForRow(at: indexPath!)!, atIndexPath: indexPath!)
configureCell(cell: tableView.cellForRow(at: indexPath!)!, atIndexPath: indexPath!)
case .move:
self.tableView.deleteRows(at: [indexPath!], with: .fade)
self.tableView.insertRows(at: [newIndexPath!], with: .fade)
tableView.deleteRows(at: [indexPath!], with: .fade)
tableView.insertRows(at: [newIndexPath!], with: .fade)
@unknown default:
fatalError("Unknown value of NSFetchedResultsChangeType")
}
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.endUpdates()
tableView.endUpdates()
}

}

Loading